From 0117a6b47eeb782e33acb4b271714e7db19c534d Mon Sep 17 00:00:00 2001 From: Mauricio Martinez Date: Thu, 17 Aug 2023 12:09:20 -0600 Subject: [PATCH 001/110] Adding requestInterceptor Signed-off-by: Mauricio Martinez --- .changeset/purple-chefs-wait.md | 5 +++ .github/vale/Vocab/Backstage/accept.txt | 1 + plugins/api-docs/README.md | 39 +++++++++++++++++++ plugins/api-docs/api-report.md | 2 +- .../OpenApiDefinition.test.tsx | 8 +++- .../OpenApiDefinition.tsx | 14 ++++++- .../OpenApiDefinitionWidget.tsx | 2 + .../OpenApiDefinitionWidget/index.ts | 4 ++ 8 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 .changeset/purple-chefs-wait.md diff --git a/.changeset/purple-chefs-wait.md b/.changeset/purple-chefs-wait.md new file mode 100644 index 0000000000..d8489e0275 --- /dev/null +++ b/.changeset/purple-chefs-wait.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-api-docs': minor +--- + +Adding requestInterceptor option to `api-docs` and pass it to SwaggerUI. This will enable to configure a proxy or headers to be sent to all the request made through the `Try it out` button on SwaggerUI. diff --git a/.github/vale/Vocab/Backstage/accept.txt b/.github/vale/Vocab/Backstage/accept.txt index c61c6bdf46..1706556ce8 100644 --- a/.github/vale/Vocab/Backstage/accept.txt +++ b/.github/vale/Vocab/Backstage/accept.txt @@ -296,6 +296,7 @@ readonly rebase Recharts Redash +requestInterceptor replicasets repo Repo diff --git a/plugins/api-docs/README.md b/plugins/api-docs/README.md index 27e19b218d..f74fc19e92 100644 --- a/plugins/api-docs/README.md +++ b/plugins/api-docs/README.md @@ -222,3 +222,42 @@ security: ## Links - [The Backstage homepage](https://backstage.io) + +### Adding requestInterceptor to Swagger UI + +To configure a [requestInterceptor for Swagger UI](https://github.com/swagger-api/swagger-ui/tree/master/flavors/swagger-ui-react#requestinterceptor-proptypesfunc) you'll need to add the following to your `api.tsx`: + +```tsx +... +import { OpenApiDefinitionWidget, apiDocsConfigRef, defaultDefinitionWidgets } from '@backstage/plugin-api-docs'; +import { ApiEntity } from '@backstage/catalog-model'; + +export const apis: AnyApiFactory[] = [ +... +createApiFactory({ + api: apiDocsConfigRef, + deps: {}, + factory: () => { + // Overriding openapi definition widget to add cors-anywhere proxy + const requestInterceptor = (req: any) => { + // Adding cors-anywhere proxy to the request url + console.log(req); + req.url = "https://cors-anywhere.herokuapp.com/" + req.url; + return req; + }; + const definitionWidgets = defaultDefinitionWidgets(); + definitionWidgets[definitionWidgets.findIndex(obj => obj.type === 'openapi')] = { + type: 'openapi', + title: 'OpenAPI', + rawLanguage: 'yaml', + component: (definition) => , + }; + + return { + getApiDefinitionWidget: (apiEntity: ApiEntity) => { + return definitionWidgets.find(d => d.type === apiEntity.spec.type); + }, + }; + }, + }) +``` diff --git a/plugins/api-docs/api-report.md b/plugins/api-docs/api-report.md index a9b21664c3..783e2bdecb 100644 --- a/plugins/api-docs/api-report.md +++ b/plugins/api-docs/api-report.md @@ -54,7 +54,7 @@ const apiDocsPlugin: BackstagePlugin< { registerApi: ExternalRouteRef; }, - {} + ApiDocsInputPluginOptions >; export { apiDocsPlugin }; export { apiDocsPlugin as plugin }; diff --git a/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinition.test.tsx b/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinition.test.tsx index 735fba86f7..adbd069908 100644 --- a/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinition.test.tsx +++ b/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinition.test.tsx @@ -38,8 +38,14 @@ paths: "200": description: Success `; + + const requestInterceptor = (req: any) => req; + const { getByText } = await renderInTestApp( - , + , ); // swagger-ui loads the documentation asynchronously diff --git a/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinition.tsx b/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinition.tsx index 5d5988399a..624f99e4a1 100644 --- a/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinition.tsx +++ b/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinition.tsx @@ -18,6 +18,7 @@ import { makeStyles } from '@material-ui/core/styles'; import React, { useEffect, useState } from 'react'; import SwaggerUI from 'swagger-ui-react'; import 'swagger-ui-react/swagger-ui.css'; +import { Request } from './'; const useStyles = makeStyles(theme => ({ root: { @@ -136,9 +137,13 @@ const useStyles = makeStyles(theme => ({ export type OpenApiDefinitionProps = { definition: string; + requestInterceptor?: (req: Request) => Request | Promise; }; -export const OpenApiDefinition = ({ definition }: OpenApiDefinitionProps) => { +export const OpenApiDefinition = ({ + definition, + requestInterceptor, +}: OpenApiDefinitionProps) => { const classes = useStyles(); // Due to a bug in the swagger-ui-react component, the component needs @@ -152,7 +157,12 @@ export const OpenApiDefinition = ({ definition }: OpenApiDefinitionProps) => { return (
- +
); }; diff --git a/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinitionWidget.tsx b/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinitionWidget.tsx index 424a52136b..809934ee11 100644 --- a/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinitionWidget.tsx +++ b/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinitionWidget.tsx @@ -16,6 +16,7 @@ import { Progress } from '@backstage/core-components'; import React, { Suspense } from 'react'; +import { Request } from './'; // The swagger-ui component and related CSS has a significant size, only load it // if the element is actually used. @@ -28,6 +29,7 @@ const LazyOpenApiDefinition = React.lazy(() => /** @public */ export type OpenApiDefinitionWidgetProps = { definition: string; + requestInterceptor?: (req: Request) => Request | Promise; }; /** @public */ diff --git a/plugins/api-docs/src/components/OpenApiDefinitionWidget/index.ts b/plugins/api-docs/src/components/OpenApiDefinitionWidget/index.ts index e317d42a59..f23f560347 100644 --- a/plugins/api-docs/src/components/OpenApiDefinitionWidget/index.ts +++ b/plugins/api-docs/src/components/OpenApiDefinitionWidget/index.ts @@ -16,3 +16,7 @@ export { OpenApiDefinitionWidget } from './OpenApiDefinitionWidget'; export type { OpenApiDefinitionWidgetProps } from './OpenApiDefinitionWidget'; + +export interface Request { + [k: string]: any; +} From d4217138351f4e3fbb89089def6467c230e99f82 Mon Sep 17 00:00:00 2001 From: Mauricio Martinez Date: Fri, 18 Aug 2023 11:01:39 -0600 Subject: [PATCH 002/110] Building api docs Signed-off-by: Mauricio Martinez --- plugins/api-docs/api-report.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/plugins/api-docs/api-report.md b/plugins/api-docs/api-report.md index 783e2bdecb..a04b3350f1 100644 --- a/plugins/api-docs/api-report.md +++ b/plugins/api-docs/api-report.md @@ -54,7 +54,7 @@ const apiDocsPlugin: BackstagePlugin< { registerApi: ExternalRouteRef; }, - ApiDocsInputPluginOptions + {} >; export { apiDocsPlugin }; export { apiDocsPlugin as plugin }; @@ -163,6 +163,7 @@ export const OpenApiDefinitionWidget: ( // @public (undocumented) export type OpenApiDefinitionWidgetProps = { definition: string; + requestInterceptor?: (req: Request_2) => Request_2 | Promise; }; // @public (undocumented) @@ -187,6 +188,15 @@ export const ProvidingComponentsCard: (props: { variant?: InfoCardVariants; }) => JSX.Element; +// Warning: (ae-missing-release-tag) "Request" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +interface Request_2 { + // (undocumented) + [k: string]: any; +} +export { Request_2 as Request }; + // @public (undocumented) export const TrpcApiDefinitionWidget: ( props: TrpcApiDefinitionWidgetProps, From 915b6ba4affeb153211cb1014ed4997e060ed6d3 Mon Sep 17 00:00:00 2001 From: Mauricio Martinez Date: Mon, 21 Aug 2023 09:35:03 -0600 Subject: [PATCH 003/110] Building api docs Signed-off-by: Mauricio Martinez --- plugins/api-docs/api-report.md | 2 -- .../api-docs/src/components/OpenApiDefinitionWidget/index.ts | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/api-docs/api-report.md b/plugins/api-docs/api-report.md index a04b3350f1..fb9fe48621 100644 --- a/plugins/api-docs/api-report.md +++ b/plugins/api-docs/api-report.md @@ -188,8 +188,6 @@ export const ProvidingComponentsCard: (props: { variant?: InfoCardVariants; }) => JSX.Element; -// Warning: (ae-missing-release-tag) "Request" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) interface Request_2 { // (undocumented) diff --git a/plugins/api-docs/src/components/OpenApiDefinitionWidget/index.ts b/plugins/api-docs/src/components/OpenApiDefinitionWidget/index.ts index f23f560347..631a96c047 100644 --- a/plugins/api-docs/src/components/OpenApiDefinitionWidget/index.ts +++ b/plugins/api-docs/src/components/OpenApiDefinitionWidget/index.ts @@ -17,6 +17,7 @@ export { OpenApiDefinitionWidget } from './OpenApiDefinitionWidget'; export type { OpenApiDefinitionWidgetProps } from './OpenApiDefinitionWidget'; +/** @public */ export interface Request { [k: string]: any; } From 3b97f2212f1c47405665026b1fe598ffc921a174 Mon Sep 17 00:00:00 2001 From: Morgan Bentell Date: Fri, 25 Aug 2023 17:28:54 +0200 Subject: [PATCH 004/110] add how to section for using other mkdocs plugins Signed-off-by: Morgan Bentell --- docs/features/techdocs/how-to-guides.md | 29 +++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/docs/features/techdocs/how-to-guides.md b/docs/features/techdocs/how-to-guides.md index b78a1a55af..2a842cd73f 100644 --- a/docs/features/techdocs/how-to-guides.md +++ b/docs/features/techdocs/how-to-guides.md @@ -675,3 +675,32 @@ entity. If the value of this annotation is `'local'`, the TechDocs backend will and publish the documentation for them. If the value of the `company.com/techdocs-builder` annotation is anything other than `'local'`, the user is responsible for publishing documentation to the appropriate location in the TechDocs external storage. + +## How to use other mkdocs plugins? + +The default plugin [mkdocs-techdocs-core](https://github.com/backstage/mkdocs-techdocs-core) provides a set of plugins that can be viewed as the minimum required plugins to enable TechDocs. Your organization might have needs beyond the core set though, here is the recommended way to enable other plugins. + +### Install the plugin + +#### With CI generation + +If you generate the HTML files in CI using `@techdocs/cli`, you need to install the desired mkdocs plugin in the runtime where the cli is being executed. This might be e.g. a docker image or a Jenkins node. Use the `--no-docker` flag with the cli to pick up the plugin you just installed. + +#### With local generation + +Create a new Docker image that extends [spotify/techdocs](https://github.com/backstage/techdocs-container), roughly: + +```Dockerfile +FROM spotify/techdocs: + +pip install +... +``` + +Then publish the image and use it in your config under the `techdocs.generator.dockerImage` [key](https://github.com/backstage/techdocs-container). + +### Specify the plugin in the mkdocs config + +To use the plugin, it has to be listed in the `mkdocs.yaml` file. You can either add the plugin to your applicable files, or specify defaults. + +To make a mkdocs plugin available for all your TechDocs components you can either list it in the `techdocs.generator.mkdocs.defaultPlugins` [config](https://github.com/backstage/backstage/blob/master/plugins/techdocs-backend/config.d.ts#L64C14-L64C14), or use the `--defaultPlugin` [cli option](https://backstage.io/docs/features/techdocs/cli#generate-techdocs-site-from-a-documentation-project) depending on your setup. From d457253de9139f866cfacebd0bb11a56f881f0af Mon Sep 17 00:00:00 2001 From: Mauricio Martinez Date: Mon, 4 Sep 2023 10:57:23 -0600 Subject: [PATCH 005/110] Comments Signed-off-by: Mauricio Martinez --- plugins/api-docs/README.md | 15 +++++++++------ plugins/api-docs/api-report.md | 9 +-------- .../OpenApiDefinitionWidget/OpenApiDefinition.tsx | 3 +-- .../OpenApiDefinitionWidget.tsx | 3 +-- .../components/OpenApiDefinitionWidget/index.ts | 5 ----- 5 files changed, 12 insertions(+), 23 deletions(-) diff --git a/plugins/api-docs/README.md b/plugins/api-docs/README.md index f74fc19e92..30c09ec483 100644 --- a/plugins/api-docs/README.md +++ b/plugins/api-docs/README.md @@ -246,12 +246,15 @@ createApiFactory({ return req; }; const definitionWidgets = defaultDefinitionWidgets(); - definitionWidgets[definitionWidgets.findIndex(obj => obj.type === 'openapi')] = { - type: 'openapi', - title: 'OpenAPI', - rawLanguage: 'yaml', - component: (definition) => , - }; + definitionWidgets.map(obj => { + if (obj.type === 'openapi') { + return { + ...obj, + component: (definition) => , + } + } + return obj; + }); return { getApiDefinitionWidget: (apiEntity: ApiEntity) => { diff --git a/plugins/api-docs/api-report.md b/plugins/api-docs/api-report.md index fb9fe48621..84e6344325 100644 --- a/plugins/api-docs/api-report.md +++ b/plugins/api-docs/api-report.md @@ -163,7 +163,7 @@ export const OpenApiDefinitionWidget: ( // @public (undocumented) export type OpenApiDefinitionWidgetProps = { definition: string; - requestInterceptor?: (req: Request_2) => Request_2 | Promise; + requestInterceptor?: (req: any) => any | Promise; }; // @public (undocumented) @@ -188,13 +188,6 @@ export const ProvidingComponentsCard: (props: { variant?: InfoCardVariants; }) => JSX.Element; -// @public (undocumented) -interface Request_2 { - // (undocumented) - [k: string]: any; -} -export { Request_2 as Request }; - // @public (undocumented) export const TrpcApiDefinitionWidget: ( props: TrpcApiDefinitionWidgetProps, diff --git a/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinition.tsx b/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinition.tsx index 624f99e4a1..a2ebbbc7e3 100644 --- a/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinition.tsx +++ b/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinition.tsx @@ -18,7 +18,6 @@ import { makeStyles } from '@material-ui/core/styles'; import React, { useEffect, useState } from 'react'; import SwaggerUI from 'swagger-ui-react'; import 'swagger-ui-react/swagger-ui.css'; -import { Request } from './'; const useStyles = makeStyles(theme => ({ root: { @@ -137,7 +136,7 @@ const useStyles = makeStyles(theme => ({ export type OpenApiDefinitionProps = { definition: string; - requestInterceptor?: (req: Request) => Request | Promise; + requestInterceptor?: (req: any) => any | Promise; }; export const OpenApiDefinition = ({ diff --git a/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinitionWidget.tsx b/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinitionWidget.tsx index 809934ee11..152f1fd089 100644 --- a/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinitionWidget.tsx +++ b/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinitionWidget.tsx @@ -16,7 +16,6 @@ import { Progress } from '@backstage/core-components'; import React, { Suspense } from 'react'; -import { Request } from './'; // The swagger-ui component and related CSS has a significant size, only load it // if the element is actually used. @@ -29,7 +28,7 @@ const LazyOpenApiDefinition = React.lazy(() => /** @public */ export type OpenApiDefinitionWidgetProps = { definition: string; - requestInterceptor?: (req: Request) => Request | Promise; + requestInterceptor?: (req: any) => any | Promise; }; /** @public */ diff --git a/plugins/api-docs/src/components/OpenApiDefinitionWidget/index.ts b/plugins/api-docs/src/components/OpenApiDefinitionWidget/index.ts index 631a96c047..e317d42a59 100644 --- a/plugins/api-docs/src/components/OpenApiDefinitionWidget/index.ts +++ b/plugins/api-docs/src/components/OpenApiDefinitionWidget/index.ts @@ -16,8 +16,3 @@ export { OpenApiDefinitionWidget } from './OpenApiDefinitionWidget'; export type { OpenApiDefinitionWidgetProps } from './OpenApiDefinitionWidget'; - -/** @public */ -export interface Request { - [k: string]: any; -} From b74b744b5ac52862f3410463fd65ae7e99bb740f Mon Sep 17 00:00:00 2001 From: Andre Wanlin <67169551+awanlin@users.noreply.github.com> Date: Mon, 11 Sep 2023 15:04:25 -0500 Subject: [PATCH 006/110] Improved docs about enableExperimentalRedirectFlow Signed-off-by: Andre Wanlin <67169551+awanlin@users.noreply.github.com> --- docs/auth/index.md | 3 +++ packages/app-defaults/CHANGELOG.md | 4 ++-- packages/core-app-api/CHANGELOG.md | 4 ++-- packages/core-components/CHANGELOG.md | 4 ++-- packages/test-utils/CHANGELOG.md | 4 ++-- plugins/auth-backend/CHANGELOG.md | 4 ++-- 6 files changed, 13 insertions(+), 10 deletions(-) diff --git a/docs/auth/index.md b/docs/auth/index.md index 0efbbcef21..91063655f2 100644 --- a/docs/auth/index.md +++ b/docs/auth/index.md @@ -140,6 +140,9 @@ const app = createApp({ }); ``` +> NOTE: You can configure sign-in to use a redirect flow with no pop-up by adding +> `enableExperimentalRedirectFlow: true` to the root of your `app-config.yaml` + ## Sign-In with Proxy Providers Some auth providers are so-called "proxy" providers, meaning they're meant to be used diff --git a/packages/app-defaults/CHANGELOG.md b/packages/app-defaults/CHANGELOG.md index 5b267a3105..1444a02501 100644 --- a/packages/app-defaults/CHANGELOG.md +++ b/packages/app-defaults/CHANGELOG.md @@ -246,7 +246,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 @@ -294,7 +294,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 diff --git a/packages/core-app-api/CHANGELOG.md b/packages/core-app-api/CHANGELOG.md index 3cd9fe309e..170ec2c52a 100644 --- a/packages/core-app-api/CHANGELOG.md +++ b/packages/core-app-api/CHANGELOG.md @@ -163,7 +163,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 @@ -224,7 +224,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 diff --git a/packages/core-components/CHANGELOG.md b/packages/core-components/CHANGELOG.md index 8fb94136e0..0a98a6d0e6 100644 --- a/packages/core-components/CHANGELOG.md +++ b/packages/core-components/CHANGELOG.md @@ -242,7 +242,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) @@ -320,7 +320,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 diff --git a/packages/test-utils/CHANGELOG.md b/packages/test-utils/CHANGELOG.md index e2170a7169..74c7d5f627 100644 --- a/packages/test-utils/CHANGELOG.md +++ b/packages/test-utils/CHANGELOG.md @@ -228,7 +228,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 @@ -286,7 +286,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 diff --git a/plugins/auth-backend/CHANGELOG.md b/plugins/auth-backend/CHANGELOG.md index f3b0c5b87c..f137cc6dbe 100644 --- a/plugins/auth-backend/CHANGELOG.md +++ b/plugins/auth-backend/CHANGELOG.md @@ -261,7 +261,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. - 475abd1dc3f: The `microsoft` (i.e. Azure) auth provider now supports negotiating tokens for Azure resources besides Microsoft Graph (e.g. AKS, Virtual Machines, Machine Learning Services, etc.). When the `/frame/handler` endpoint is called with an @@ -347,7 +347,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 From aad197a601e9ba981452d86068af5cf944ec9c76 Mon Sep 17 00:00:00 2001 From: Mauricio Martinez Date: Mon, 11 Sep 2023 17:42:51 -0600 Subject: [PATCH 007/110] Update definitionWidgets to map instead of forEach loop Signed-off-by: Mauricio Martinez --- plugins/api-docs/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/api-docs/README.md b/plugins/api-docs/README.md index 30c09ec483..1f8a9b8db3 100644 --- a/plugins/api-docs/README.md +++ b/plugins/api-docs/README.md @@ -245,8 +245,7 @@ createApiFactory({ req.url = "https://cors-anywhere.herokuapp.com/" + req.url; return req; }; - const definitionWidgets = defaultDefinitionWidgets(); - definitionWidgets.map(obj => { + const definitionWidgets = defaultDefinitionWidgets().map(obj => { if (obj.type === 'openapi') { return { ...obj, From 05880e8c0a3c9c5b7315d306ab357e428bfaab4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mauricio=20Alejandro=20Mart=C3=ADnez=20Pacheco?= Date: Tue, 12 Sep 2023 12:31:03 -0600 Subject: [PATCH 008/110] Update .changeset/purple-chefs-wait.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Patrik Oldsberg Signed-off-by: Mauricio Alejandro Martínez Pacheco --- .changeset/purple-chefs-wait.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/purple-chefs-wait.md b/.changeset/purple-chefs-wait.md index d8489e0275..36cbe99095 100644 --- a/.changeset/purple-chefs-wait.md +++ b/.changeset/purple-chefs-wait.md @@ -2,4 +2,4 @@ '@backstage/plugin-api-docs': minor --- -Adding requestInterceptor option to `api-docs` and pass it to SwaggerUI. This will enable to configure a proxy or headers to be sent to all the request made through the `Try it out` button on SwaggerUI. +Adding `requestInterceptor` option to `api-docs` and pass it to SwaggerUI. This will enable to configure a proxy or headers to be sent to all the request made through the `Try it out` button on SwaggerUI. From f3561a2935387fbdf969eee80a567de14444ebd1 Mon Sep 17 00:00:00 2001 From: Andrew Thauer Date: Tue, 12 Sep 2023 15:28:12 -0400 Subject: [PATCH 009/110] feat(catalog): include owner in search result item Signed-off-by: Andrew Thauer --- .changeset/lemon-cups-wait.md | 5 +++++ .../CatalogSearchResultListItem.tsx | 3 +++ 2 files changed, 8 insertions(+) create mode 100644 .changeset/lemon-cups-wait.md diff --git a/.changeset/lemon-cups-wait.md b/.changeset/lemon-cups-wait.md new file mode 100644 index 0000000000..4dd08c21b0 --- /dev/null +++ b/.changeset/lemon-cups-wait.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog': minor +--- + +include owner chip in catalog search result item diff --git a/plugins/catalog/src/components/CatalogSearchResultListItem/CatalogSearchResultListItem.tsx b/plugins/catalog/src/components/CatalogSearchResultListItem/CatalogSearchResultListItem.tsx index 50caf4ff8a..06906aecc1 100644 --- a/plugins/catalog/src/components/CatalogSearchResultListItem/CatalogSearchResultListItem.tsx +++ b/plugins/catalog/src/components/CatalogSearchResultListItem/CatalogSearchResultListItem.tsx @@ -110,6 +110,9 @@ export function CatalogSearchResultListItem( {result.lifecycle && ( )} + {result.owner && ( + + )} From 902ea9cb266c1ce89a92e3771b8e8a435af1807b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mauricio=20Alejandro=20Mart=C3=ADnez=20Pacheco?= Date: Tue, 12 Sep 2023 14:09:15 -0600 Subject: [PATCH 010/110] Update .github/vale/Vocab/Backstage/accept.txt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Patrik Oldsberg Signed-off-by: Mauricio Alejandro Martínez Pacheco --- .github/vale/Vocab/Backstage/accept.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/vale/Vocab/Backstage/accept.txt b/.github/vale/Vocab/Backstage/accept.txt index 1706556ce8..c61c6bdf46 100644 --- a/.github/vale/Vocab/Backstage/accept.txt +++ b/.github/vale/Vocab/Backstage/accept.txt @@ -296,7 +296,6 @@ readonly rebase Recharts Redash -requestInterceptor replicasets repo Repo From 03c9e4c5704d0d64794d117e2fb362fa90d3b351 Mon Sep 17 00:00:00 2001 From: Mauricio Martinez Date: Tue, 12 Sep 2023 14:17:06 -0600 Subject: [PATCH 011/110] Remove cors-anywhere example in favor of simple header change Signed-off-by: Mauricio Martinez --- plugins/api-docs/README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/plugins/api-docs/README.md b/plugins/api-docs/README.md index 1f8a9b8db3..ceddab540a 100644 --- a/plugins/api-docs/README.md +++ b/plugins/api-docs/README.md @@ -238,11 +238,9 @@ createApiFactory({ api: apiDocsConfigRef, deps: {}, factory: () => { - // Overriding openapi definition widget to add cors-anywhere proxy + // Overriding openapi definition widget to add header const requestInterceptor = (req: any) => { - // Adding cors-anywhere proxy to the request url - console.log(req); - req.url = "https://cors-anywhere.herokuapp.com/" + req.url; + req.headers.append('myheader', 'wombats'); return req; }; const definitionWidgets = defaultDefinitionWidgets().map(obj => { From e3993a0f3ba96b9ec1f12fcbbd98aff12d52c100 Mon Sep 17 00:00:00 2001 From: Mauricio Martinez Date: Tue, 12 Sep 2023 14:19:22 -0600 Subject: [PATCH 012/110] Adding ticks to requestInterceptor on docs to avoid spell change Signed-off-by: Mauricio Martinez --- plugins/api-docs/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/api-docs/README.md b/plugins/api-docs/README.md index ceddab540a..792a7fb0b7 100644 --- a/plugins/api-docs/README.md +++ b/plugins/api-docs/README.md @@ -223,9 +223,9 @@ security: - [The Backstage homepage](https://backstage.io) -### Adding requestInterceptor to Swagger UI +### Adding `requestInterceptor` to Swagger UI -To configure a [requestInterceptor for Swagger UI](https://github.com/swagger-api/swagger-ui/tree/master/flavors/swagger-ui-react#requestinterceptor-proptypesfunc) you'll need to add the following to your `api.tsx`: +To configure a [`requestInterceptor` for Swagger UI](https://github.com/swagger-api/swagger-ui/tree/master/flavors/swagger-ui-react#requestinterceptor-proptypesfunc) you'll need to add the following to your `api.tsx`: ```tsx ... From df449a7a3132996a80b3a98ec3157f60f38a8ab7 Mon Sep 17 00:00:00 2001 From: Heikki Hellgren Date: Mon, 11 Sep 2023 13:13:22 +0300 Subject: [PATCH 013/110] chore: add kind column by default to TechDocsTable Signed-off-by: Heikki Hellgren --- .changeset/stupid-drinks-trade.md | 5 +++++ plugins/techdocs/api-report.md | 2 ++ plugins/techdocs/src/home/components/Tables/DocsTable.tsx | 7 ++++--- plugins/techdocs/src/home/components/Tables/columns.tsx | 6 ++++++ 4 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 .changeset/stupid-drinks-trade.md diff --git a/.changeset/stupid-drinks-trade.md b/.changeset/stupid-drinks-trade.md new file mode 100644 index 0000000000..a9eeacec8a --- /dev/null +++ b/.changeset/stupid-drinks-trade.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs': patch +--- + +Add kind column by default to TechDocsTable diff --git a/plugins/techdocs/api-report.md b/plugins/techdocs/api-report.md index 3207a16f87..f355fd00d2 100644 --- a/plugins/techdocs/api-report.md +++ b/plugins/techdocs/api-report.md @@ -79,6 +79,7 @@ export const DocsTable: { columns: { createNameColumn(): TableColumn; createOwnerColumn(): TableColumn; + createKindColumn(): TableColumn; createTypeColumn(): TableColumn; }; actions: { @@ -142,6 +143,7 @@ export const EntityListDocsTable: { columns: { createNameColumn(): TableColumn; createOwnerColumn(): TableColumn; + createKindColumn(): TableColumn; createTypeColumn(): TableColumn; }; actions: { diff --git a/plugins/techdocs/src/home/components/Tables/DocsTable.tsx b/plugins/techdocs/src/home/components/Tables/DocsTable.tsx index 5e5b41ee3e..03ba442578 100644 --- a/plugins/techdocs/src/home/components/Tables/DocsTable.tsx +++ b/plugins/techdocs/src/home/components/Tables/DocsTable.tsx @@ -17,16 +17,16 @@ import React from 'react'; import useCopyToClipboard from 'react-use/lib/useCopyToClipboard'; -import { useRouteRef, useApi, configApiRef } from '@backstage/core-plugin-api'; +import { configApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api'; import { Entity, RELATION_OWNED_BY } from '@backstage/catalog-model'; import { - humanizeEntityRef, getEntityRelations, + humanizeEntityRef, } from '@backstage/plugin-catalog-react'; import { rootDocsRouteRef } from '../../../routes'; import { - LinkButton, EmptyState, + LinkButton, Table, TableColumn, TableOptions, @@ -87,6 +87,7 @@ export const DocsTable = (props: DocsTableProps) => { const defaultColumns: TableColumn[] = [ columnFactories.createNameColumn(), columnFactories.createOwnerColumn(), + columnFactories.createKindColumn(), columnFactories.createTypeColumn(), ]; diff --git a/plugins/techdocs/src/home/components/Tables/columns.tsx b/plugins/techdocs/src/home/components/Tables/columns.tsx index 774cfc5e8a..bc85bb7a63 100644 --- a/plugins/techdocs/src/home/components/Tables/columns.tsx +++ b/plugins/techdocs/src/home/components/Tables/columns.tsx @@ -57,6 +57,12 @@ export const columnFactories = { ), }; }, + createKindColumn(): TableColumn { + return { + title: 'Kind', + field: 'entity.kind', + }; + }, createTypeColumn(): TableColumn { return { title: 'Type', From 00cf54df4c11721edbd8c96ced380ccf2870e97f Mon Sep 17 00:00:00 2001 From: zcason Date: Mon, 18 Sep 2023 11:25:00 -0500 Subject: [PATCH 014/110] migrate graphql-backend plugin to the new backend system Signed-off-by: zcason --- packages/backend-next/package.json | 1 + packages/backend-next/src/index.ts | 1 + plugins/graphql-backend/api-report.md | 5 ++++ plugins/graphql-backend/src/index.ts | 1 + plugins/graphql-backend/src/plugin.ts | 42 +++++++++++++++++++++++++++ yarn.lock | 2 ++ 6 files changed, 52 insertions(+) create mode 100644 plugins/graphql-backend/src/plugin.ts diff --git a/packages/backend-next/package.json b/packages/backend-next/package.json index edda247a5a..6952fdcc7a 100644 --- a/packages/backend-next/package.json +++ b/packages/backend-next/package.json @@ -38,6 +38,7 @@ "@backstage/plugin-catalog-backend-module-unprocessed": "workspace:^", "@backstage/plugin-devtools-backend": "workspace:^", "@backstage/plugin-entity-feedback-backend": "workspace:^", + "@backstage/plugin-graphql-backend": "workspace:^", "@backstage/plugin-kubernetes-backend": "workspace:^", "@backstage/plugin-lighthouse-backend": "workspace:^", "@backstage/plugin-linguist-backend": "workspace:^", diff --git a/packages/backend-next/src/index.ts b/packages/backend-next/src/index.ts index 4e99732a11..b6ffa11a21 100644 --- a/packages/backend-next/src/index.ts +++ b/packages/backend-next/src/index.ts @@ -29,6 +29,7 @@ backend.add( backend.add(import('@backstage/plugin-catalog-backend/alpha')); backend.add(import('@backstage/plugin-devtools-backend')); backend.add(import('@backstage/plugin-entity-feedback-backend')); +backend.add(import('@backstage/plugin-graphql-backend')); backend.add(import('@backstage/plugin-kubernetes-backend/alpha')); backend.add(import('@backstage/plugin-lighthouse-backend')); backend.add(import('@backstage/plugin-linguist-backend')); diff --git a/plugins/graphql-backend/api-report.md b/plugins/graphql-backend/api-report.md index a787c4f209..31cdf4c617 100644 --- a/plugins/graphql-backend/api-report.md +++ b/plugins/graphql-backend/api-report.md @@ -3,6 +3,7 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; import { Config } from '@backstage/config'; import express from 'express'; import { Logger } from 'winston'; @@ -10,6 +11,10 @@ import { Logger } from 'winston'; // @public (undocumented) export function createRouter(options: RouterOptions): Promise; +// @public +const graphqlPlugin: () => BackendFeature; +export default graphqlPlugin; + // @public (undocumented) export interface RouterOptions { // (undocumented) diff --git a/plugins/graphql-backend/src/index.ts b/plugins/graphql-backend/src/index.ts index a9f7f92ad9..5c21db501f 100644 --- a/plugins/graphql-backend/src/index.ts +++ b/plugins/graphql-backend/src/index.ts @@ -21,3 +21,4 @@ */ export * from './service/router'; +export { graphqlPlugin as default } from './plugin'; diff --git a/plugins/graphql-backend/src/plugin.ts b/plugins/graphql-backend/src/plugin.ts new file mode 100644 index 0000000000..6401f87803 --- /dev/null +++ b/plugins/graphql-backend/src/plugin.ts @@ -0,0 +1,42 @@ +/* + * 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 { + coreServices, + createBackendPlugin, +} from '@backstage/backend-plugin-api'; +import { createRouter } from './service/router'; +import { loggerToWinstonLogger } from '@backstage/backend-common'; + +export const graphqlPlugin = createBackendPlugin({ + pluginId: 'graphql', + register(env) { + env.registerInit({ + deps: { + config: coreServices.rootConfig, + http: coreServices.httpRouter, + logger: coreServices.logger, + }, + async init({ config, http, logger }) { + http.use( + await createRouter({ + config, + logger: loggerToWinstonLogger(logger), + }), + ); + }, + }); + }, +}); diff --git a/yarn.lock b/yarn.lock index 84ad190c8a..53f1c4052a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7280,6 +7280,7 @@ __metadata: dependencies: "@apollo/server": ^4.0.0 "@backstage/backend-common": "workspace:^" + "@backstage/backend-plugin-api": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" "@backstage/plugin-catalog-graphql": "workspace:^" @@ -25960,6 +25961,7 @@ __metadata: "@backstage/plugin-catalog-backend-module-unprocessed": "workspace:^" "@backstage/plugin-devtools-backend": "workspace:^" "@backstage/plugin-entity-feedback-backend": "workspace:^" + "@backstage/plugin-graphql-backend": "workspace:^" "@backstage/plugin-kubernetes-backend": "workspace:^" "@backstage/plugin-lighthouse-backend": "workspace:^" "@backstage/plugin-linguist-backend": "workspace:^" From ee7d8a737b6314ee765d342c09638794f686de35 Mon Sep 17 00:00:00 2001 From: zcason Date: Mon, 18 Sep 2023 11:26:23 -0500 Subject: [PATCH 015/110] migrate graphql-backend plugin to the new backend system Signed-off-by: zcason --- plugins/graphql-backend/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/graphql-backend/package.json b/plugins/graphql-backend/package.json index 7582c150cb..2ed420983e 100644 --- a/plugins/graphql-backend/package.json +++ b/plugins/graphql-backend/package.json @@ -35,6 +35,7 @@ "dependencies": { "@apollo/server": "^4.0.0", "@backstage/backend-common": "workspace:^", + "@backstage/backend-plugin-api": "workspace:^", "@backstage/config": "workspace:^", "@backstage/plugin-catalog-graphql": "workspace:^", "@graphql-tools/schema": "^9.0.0", From 4a2d633aae18fcdb73c0aca1aff226aead535d93 Mon Sep 17 00:00:00 2001 From: zcason Date: Mon, 18 Sep 2023 15:26:57 -0500 Subject: [PATCH 016/110] migrate playlist-backend plugin to the new backend system Signed-off-by: zcason --- packages/backend-next/package.json | 1 + packages/backend-next/src/index.ts | 1 + plugins/playlist-backend/api-report.md | 4 +++ plugins/playlist-backend/package.json | 1 + plugins/playlist-backend/src/index.ts | 1 + plugins/playlist-backend/src/plugin.ts | 48 ++++++++++++++++++++++++++ yarn.lock | 2 ++ 7 files changed, 58 insertions(+) create mode 100644 plugins/playlist-backend/src/plugin.ts diff --git a/packages/backend-next/package.json b/packages/backend-next/package.json index 6952fdcc7a..e7b52f7ad0 100644 --- a/packages/backend-next/package.json +++ b/packages/backend-next/package.json @@ -46,6 +46,7 @@ "@backstage/plugin-permission-backend-module-allow-all-policy": "workspace:^", "@backstage/plugin-permission-common": "workspace:^", "@backstage/plugin-permission-node": "workspace:^", + "@backstage/plugin-playlist-backend": "workspace:^", "@backstage/plugin-proxy-backend": "workspace:^", "@backstage/plugin-scaffolder-backend": "workspace:^", "@backstage/plugin-search-backend": "workspace:^", diff --git a/packages/backend-next/src/index.ts b/packages/backend-next/src/index.ts index b6ffa11a21..68e33f4be3 100644 --- a/packages/backend-next/src/index.ts +++ b/packages/backend-next/src/index.ts @@ -33,6 +33,7 @@ backend.add(import('@backstage/plugin-graphql-backend')); backend.add(import('@backstage/plugin-kubernetes-backend/alpha')); backend.add(import('@backstage/plugin-lighthouse-backend')); backend.add(import('@backstage/plugin-linguist-backend')); +backend.add(import('@backstage/plugin-playlist-backend')); backend.add( import('@backstage/plugin-permission-backend-module-allow-all-policy'), ); diff --git a/plugins/playlist-backend/api-report.md b/plugins/playlist-backend/api-report.md index 6b51f316c4..cc7d478481 100644 --- a/plugins/playlist-backend/api-report.md +++ b/plugins/playlist-backend/api-report.md @@ -3,6 +3,7 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; import { BackstageIdentityResponse } from '@backstage/plugin-auth-node'; import { ConditionalPolicyDecision } from '@backstage/plugin-permission-common'; import { Conditions } from '@backstage/plugin-permission-node'; @@ -34,6 +35,9 @@ export const createPlaylistConditionalDecision: ( // @public (undocumented) export function createRouter(options: RouterOptions): Promise; +// @public +export const playlistPlugin: () => BackendFeature; + // @public export class DefaultPlaylistPermissionPolicy implements PermissionPolicy { // (undocumented) diff --git a/plugins/playlist-backend/package.json b/plugins/playlist-backend/package.json index 53a3bff88a..7189a14b86 100644 --- a/plugins/playlist-backend/package.json +++ b/plugins/playlist-backend/package.json @@ -29,6 +29,7 @@ }, "dependencies": { "@backstage/backend-common": "workspace:^", + "@backstage/backend-plugin-api": "workspace:^", "@backstage/catalog-client": "workspace:^", "@backstage/catalog-model": "workspace:^", "@backstage/config": "workspace:^", diff --git a/plugins/playlist-backend/src/index.ts b/plugins/playlist-backend/src/index.ts index eeccd8913f..9081552e00 100644 --- a/plugins/playlist-backend/src/index.ts +++ b/plugins/playlist-backend/src/index.ts @@ -26,3 +26,4 @@ export { isPlaylistPermission, playlistConditions, } from './permissions'; +export { playlistPlugin as default } from './plugin'; diff --git a/plugins/playlist-backend/src/plugin.ts b/plugins/playlist-backend/src/plugin.ts new file mode 100644 index 0000000000..12fe94b01a --- /dev/null +++ b/plugins/playlist-backend/src/plugin.ts @@ -0,0 +1,48 @@ +/* + * 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 { + coreServices, + createBackendPlugin, +} from '@backstage/backend-plugin-api'; +import { createRouter } from './service'; +import { loggerToWinstonLogger } from '@backstage/backend-common'; + +export const playlistPlugin = createBackendPlugin({ + pluginId: 'playlist', + register(env) { + env.registerInit({ + deps: { + http: coreServices.httpRouter, + logger: coreServices.logger, + database: coreServices.database, + identity: coreServices.identity, + discovery: coreServices.discovery, + permissions: coreServices.permissions, + }, + async init({ http, logger, database, identity, discovery, permissions }) { + http.use( + await createRouter({ + logger: loggerToWinstonLogger(logger), + database, + identity, + discovery, + permissions, + }), + ); + }, + }); + }, +}); diff --git a/yarn.lock b/yarn.lock index 53f1c4052a..d600d02811 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8362,6 +8362,7 @@ __metadata: resolution: "@backstage/plugin-playlist-backend@workspace:plugins/playlist-backend" dependencies: "@backstage/backend-common": "workspace:^" + "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/catalog-client": "workspace:^" "@backstage/catalog-model": "workspace:^" @@ -25969,6 +25970,7 @@ __metadata: "@backstage/plugin-permission-backend-module-allow-all-policy": "workspace:^" "@backstage/plugin-permission-common": "workspace:^" "@backstage/plugin-permission-node": "workspace:^" + "@backstage/plugin-playlist-backend": "workspace:^" "@backstage/plugin-proxy-backend": "workspace:^" "@backstage/plugin-scaffolder-backend": "workspace:^" "@backstage/plugin-search-backend": "workspace:^" From 1bb94045a63f1eae2a06665e635763fc79e36ed8 Mon Sep 17 00:00:00 2001 From: zcason Date: Mon, 18 Sep 2023 15:33:03 -0500 Subject: [PATCH 017/110] added support to graphql and playlist for new backend Signed-off-by: zcason --- .changeset/eighty-wasps-remain.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/eighty-wasps-remain.md diff --git a/.changeset/eighty-wasps-remain.md b/.changeset/eighty-wasps-remain.md new file mode 100644 index 0000000000..e6ecfde660 --- /dev/null +++ b/.changeset/eighty-wasps-remain.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-playlist-backend': patch +'@backstage/plugin-graphql-backend': patch +--- + +Added support to graphql and playlist for new backend From 0b5845f6c1e7ae078a1e4de81fb6bb721a5e84c7 Mon Sep 17 00:00:00 2001 From: zcason Date: Mon, 18 Sep 2023 15:53:56 -0500 Subject: [PATCH 018/110] updated read me for newly supported plugins Signed-off-by: zcason --- plugins/graphql-backend/README.md | 15 +++++++++++++++ plugins/playlist-backend/README.md | 18 ++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/plugins/graphql-backend/README.md b/plugins/graphql-backend/README.md index 970222fb1f..11453ec8bc 100644 --- a/plugins/graphql-backend/README.md +++ b/plugins/graphql-backend/README.md @@ -26,3 +26,18 @@ yarn workspace example-backend start ``` This will launch the full example backend. + +### New Backend System + +The Grahpql backend plugin has support for the [new backend system](https://backstage.io/docs/backend-system/), here's how you can set that up: +In your `packages/backend/src/index.ts` make the following changes: + +```diff ++ import { graphqlPlugin } from '@backstage/plugin-graphql-backend'; + +const backend = createBackend(); ++ backend.add(graphqlPlugin()); +// ... other feature additions + +backend.start(); +``` diff --git a/plugins/playlist-backend/README.md b/plugins/playlist-backend/README.md index c0055ebdf7..e336ec5b08 100644 --- a/plugins/playlist-backend/README.md +++ b/plugins/playlist-backend/README.md @@ -85,3 +85,21 @@ export default async function createPlugin(env: PluginEnvironment): Promise Date: Tue, 19 Sep 2023 14:29:33 +0200 Subject: [PATCH 019/110] tech-radar: Add alpha exports for page and api extensions Signed-off-by: Johan Haals --- packages/app-next/src/App.tsx | 3 +- plugins/tech-radar/alpha-api-report.md | 24 ++++++++++ plugins/tech-radar/package.json | 16 +++++++ plugins/tech-radar/src/alpha.tsx | 64 ++++++++++++++++++++++++++ 4 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 plugins/tech-radar/alpha-api-report.md create mode 100644 plugins/tech-radar/src/alpha.tsx diff --git a/packages/app-next/src/App.tsx b/packages/app-next/src/App.tsx index aa9bb985c2..d844939cf2 100644 --- a/packages/app-next/src/App.tsx +++ b/packages/app-next/src/App.tsx @@ -17,6 +17,7 @@ import { createApp } from '@backstage/frontend-app-api'; import { pagesPlugin } from './examples/pagesPlugin'; import graphiqlPlugin from '@backstage/plugin-graphiql/alpha'; +import techRadarPlugin from '@backstage/plugin-tech-radar/alpha'; /* @@ -48,7 +49,7 @@ TODO: /* app.tsx */ const app = createApp({ - plugins: [graphiqlPlugin, pagesPlugin], + plugins: [graphiqlPlugin, pagesPlugin, techRadarPlugin], // bindRoutes({ bind }) { // bind(catalogPlugin.externalRoutes, { // createComponent: scaffolderPlugin.routes.root, diff --git a/plugins/tech-radar/alpha-api-report.md b/plugins/tech-radar/alpha-api-report.md new file mode 100644 index 0000000000..23c5d5d353 --- /dev/null +++ b/plugins/tech-radar/alpha-api-report.md @@ -0,0 +1,24 @@ +## API Report File for "@backstage/plugin-tech-radar" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackstagePlugin } from '@backstage/frontend-plugin-api'; +import { Extension } from '@backstage/frontend-plugin-api'; + +// @alpha (undocumented) +const _default: BackstagePlugin; +export default _default; + +// @alpha (undocumented) +export const TechRadarPage: Extension<{ + height: number; + width: number; + title: string; + path: string; + pageTitle: string; + subTitle: string; +}>; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/tech-radar/package.json b/plugins/tech-radar/package.json index 1b048f49cd..300f3cd69a 100644 --- a/plugins/tech-radar/package.json +++ b/plugins/tech-radar/package.json @@ -22,6 +22,21 @@ "keywords": [ "backstage" ], + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.tsx", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.tsx" + ], + "package.json": [ + "package.json" + ] + } + }, "sideEffects": false, "scripts": { "build": "backstage-cli package build", @@ -35,6 +50,7 @@ "dependencies": { "@backstage/core-components": "workspace:^", "@backstage/core-plugin-api": "workspace:^", + "@backstage/frontend-plugin-api": "workspace:^", "@backstage/theme": "workspace:^", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", diff --git a/plugins/tech-radar/src/alpha.tsx b/plugins/tech-radar/src/alpha.tsx new file mode 100644 index 0000000000..29b170c957 --- /dev/null +++ b/plugins/tech-radar/src/alpha.tsx @@ -0,0 +1,64 @@ +/* + * 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 { createApiFactory, createRouteRef } from '@backstage/core-plugin-api'; +import { + createApiExtension, + createPageExtension, + createPlugin, + createSchemaFromZod, +} from '@backstage/frontend-plugin-api'; +import React from 'react'; +import { techRadarApiRef } from './api'; +import { SampleTechRadarApi } from './sample'; + +const techRadarRouteRef = createRouteRef({ id: 'plugin.techradar.page' }); + +/** @alpha */ +export const TechRadarPage = createPageExtension({ + id: 'plugin.techradar.page', + defaultPath: '/tech-radar', + routeRef: techRadarRouteRef, + configSchema: createSchemaFromZod(z => + z.object({ + title: z.string().default('Tech Radar'), + subTitle: z + .string() + .default('Pick the recommended technologies for your projects'), + pageTitle: z.string().default('Company Radar'), + path: z.string().default('/tech-radar'), + width: z.number().default(1500), + height: z.number().default(800), + }), + ), + loader: ({ config }) => + import('./components').then(m => ( + + )), +}); + +const sampleTechRadarApi = createApiExtension({ + api: techRadarApiRef, + factory() { + return createApiFactory(techRadarApiRef, new SampleTechRadarApi()); + }, +}); + +/** @alpha */ +export default createPlugin({ + id: 'tech-radar', + extensions: [TechRadarPage, sampleTechRadarApi], +}); From 4bd4648309b2a859e75f889183c618b0071e834c Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Tue, 19 Sep 2023 14:32:08 +0200 Subject: [PATCH 020/110] chore: update lockfile Signed-off-by: Johan Haals --- yarn.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/yarn.lock b/yarn.lock index c0a75005bf..b4dea1bb1e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9523,6 +9523,7 @@ __metadata: "@backstage/core-components": "workspace:^" "@backstage/core-plugin-api": "workspace:^" "@backstage/dev-utils": "workspace:^" + "@backstage/frontend-plugin-api": "workspace:^" "@backstage/test-utils": "workspace:^" "@backstage/theme": "workspace:^" "@material-ui/core": ^4.12.2 From c09d2fa1d64aedd10afc7d1eec4cac152b58a9a5 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Tue, 19 Sep 2023 14:34:29 +0200 Subject: [PATCH 021/110] add changeset Signed-off-by: Johan Haals --- .changeset/lovely-fans-sniff.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/lovely-fans-sniff.md diff --git a/.changeset/lovely-fans-sniff.md b/.changeset/lovely-fans-sniff.md new file mode 100644 index 0000000000..af8aebb89b --- /dev/null +++ b/.changeset/lovely-fans-sniff.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-tech-radar': patch +--- + +Added experimental support for the declarative integration. From 2db1ea8f6b5224546e5b31b4bd953d613f7d9a42 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Tue, 19 Sep 2023 15:46:20 +0200 Subject: [PATCH 022/110] fix package.json Signed-off-by: Johan Haals --- plugins/tech-radar/package.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/plugins/tech-radar/package.json b/plugins/tech-radar/package.json index 300f3cd69a..ca19324f27 100644 --- a/plugins/tech-radar/package.json +++ b/plugins/tech-radar/package.json @@ -6,9 +6,7 @@ "types": "src/index.ts", "license": "Apache-2.0", "publishConfig": { - "access": "public", - "main": "dist/index.esm.js", - "types": "dist/index.d.ts" + "access": "public" }, "backstage": { "role": "frontend-plugin" From b97e9790f0894f8f92c2541abd680c59fd42019e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Thu, 25 May 2023 14:40:12 +0200 Subject: [PATCH 023/110] Internal refactors as a path toward #18062 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/polite-donuts-fail.md | 5 + .../src/database/DefaultProcessingDatabase.ts | 6 - .../stitcher}/buildEntitySearch.test.ts | 2 +- .../operations/stitcher}/buildEntitySearch.ts | 4 +- .../stitcher/markForStitching.test.ts | 260 ++++++++++++++++ .../operations/stitcher/markForStitching.ts | 82 +++++ .../stitcher/performStitching.test.ts | 287 ++++++++++++++++++ .../operations/stitcher/performStitching.ts | 236 ++++++++++++++ .../operations/stitcher}/util.ts | 0 .../util/deleteOrphanedEntities.test.ts | 36 ++- .../operations/util/deleteOrphanedEntities.ts | 34 +-- .../catalog-backend/src/database/tables.ts | 73 ++++- plugins/catalog-backend/src/database/types.ts | 2 - .../DefaultCatalogProcessingEngine.test.ts | 20 +- .../DefaultCatalogProcessingEngine.ts | 63 ++-- .../catalog-backend/src/processing/types.ts | 4 +- .../src/service/CatalogBuilder.ts | 20 +- .../service/DefaultEntitiesCatalog.test.ts | 10 +- .../src/service/DefaultEntitiesCatalog.ts | 7 +- .../src/service/DefaultRefreshService.test.ts | 9 +- ...itcher.test.ts => DefaultStitcher.test.ts} | 14 +- .../src/stitching/DefaultStitcher.ts | 124 ++++++++ .../catalog-backend/src/stitching/Stitcher.ts | 250 --------------- .../src/stitching/progressTracker.ts | 84 +++++ .../catalog-backend/src/stitching/types.ts | 40 +++ .../src/tests/integration.test.ts | 16 +- .../performance/stitchingPerformance.test.ts | 2 +- 27 files changed, 1335 insertions(+), 355 deletions(-) create mode 100644 .changeset/polite-donuts-fail.md rename plugins/catalog-backend/src/{stitching => database/operations/stitcher}/buildEntitySearch.test.ts (99%) rename plugins/catalog-backend/src/{stitching => database/operations/stitcher}/buildEntitySearch.ts (98%) create mode 100644 plugins/catalog-backend/src/database/operations/stitcher/markForStitching.test.ts create mode 100644 plugins/catalog-backend/src/database/operations/stitcher/markForStitching.ts create mode 100644 plugins/catalog-backend/src/database/operations/stitcher/performStitching.test.ts create mode 100644 plugins/catalog-backend/src/database/operations/stitcher/performStitching.ts rename plugins/catalog-backend/src/{stitching => database/operations/stitcher}/util.ts (100%) rename plugins/catalog-backend/src/stitching/{Stitcher.test.ts => DefaultStitcher.test.ts} (95%) create mode 100644 plugins/catalog-backend/src/stitching/DefaultStitcher.ts delete mode 100644 plugins/catalog-backend/src/stitching/Stitcher.ts create mode 100644 plugins/catalog-backend/src/stitching/progressTracker.ts create mode 100644 plugins/catalog-backend/src/stitching/types.ts diff --git a/.changeset/polite-donuts-fail.md b/.changeset/polite-donuts-fail.md new file mode 100644 index 0000000000..4b71dfddc3 --- /dev/null +++ b/.changeset/polite-donuts-fail.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': patch +--- + +Internal refactors as a path toward #18062 diff --git a/plugins/catalog-backend/src/database/DefaultProcessingDatabase.ts b/plugins/catalog-backend/src/database/DefaultProcessingDatabase.ts index 01025f73dd..2daf8e6fc5 100644 --- a/plugins/catalog-backend/src/database/DefaultProcessingDatabase.ts +++ b/plugins/catalog-backend/src/database/DefaultProcessingDatabase.ts @@ -42,7 +42,6 @@ import { import { checkLocationKeyConflict } from './operations/refreshState/checkLocationKeyConflict'; import { insertUnprocessedEntity } from './operations/refreshState/insertUnprocessedEntity'; import { updateUnprocessedEntity } from './operations/refreshState/updateUnprocessedEntity'; -import { deleteOrphanedEntities } from './operations/util/deleteOrphanedEntities'; import { generateStableHash } from './util'; import { EventBroker, EventParams } from '@backstage/plugin-events-node'; import { DateTime } from 'luxon'; @@ -275,11 +274,6 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { return { entityRefs }; } - async deleteOrphanedEntities(txOpaque: Transaction): Promise { - const tx = txOpaque as Knex.Transaction; - return await deleteOrphanedEntities({ tx }); - } - async transaction(fn: (tx: Transaction) => Promise): Promise { try { let result: T | undefined = undefined; diff --git a/plugins/catalog-backend/src/stitching/buildEntitySearch.test.ts b/plugins/catalog-backend/src/database/operations/stitcher/buildEntitySearch.test.ts similarity index 99% rename from plugins/catalog-backend/src/stitching/buildEntitySearch.test.ts rename to plugins/catalog-backend/src/database/operations/stitcher/buildEntitySearch.test.ts index 384794d230..8bc5ba57a9 100644 --- a/plugins/catalog-backend/src/stitching/buildEntitySearch.test.ts +++ b/plugins/catalog-backend/src/database/operations/stitcher/buildEntitySearch.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { Entity, DEFAULT_NAMESPACE } from '@backstage/catalog-model'; +import { DEFAULT_NAMESPACE, Entity } from '@backstage/catalog-model'; import { buildEntitySearch, mapToRows, traverse } from './buildEntitySearch'; describe('buildEntitySearch', () => { diff --git a/plugins/catalog-backend/src/stitching/buildEntitySearch.ts b/plugins/catalog-backend/src/database/operations/stitcher/buildEntitySearch.ts similarity index 98% rename from plugins/catalog-backend/src/stitching/buildEntitySearch.ts rename to plugins/catalog-backend/src/database/operations/stitcher/buildEntitySearch.ts index b97083f207..30f2987cb5 100644 --- a/plugins/catalog-backend/src/stitching/buildEntitySearch.ts +++ b/plugins/catalog-backend/src/database/operations/stitcher/buildEntitySearch.ts @@ -14,9 +14,9 @@ * limitations under the License. */ -import { Entity, DEFAULT_NAMESPACE } from '@backstage/catalog-model'; +import { DEFAULT_NAMESPACE, Entity } from '@backstage/catalog-model'; import { InputError } from '@backstage/errors'; -import { DbSearchRow } from '../database/tables'; +import { DbSearchRow } from '../../tables'; // These are excluded in the generic loop, either because they do not make sense // to index, or because they are special-case always inserted whether they are diff --git a/plugins/catalog-backend/src/database/operations/stitcher/markForStitching.test.ts b/plugins/catalog-backend/src/database/operations/stitcher/markForStitching.test.ts new file mode 100644 index 0000000000..ce44fe15d8 --- /dev/null +++ b/plugins/catalog-backend/src/database/operations/stitcher/markForStitching.test.ts @@ -0,0 +1,260 @@ +/* + * 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 { TestDatabases } from '@backstage/backend-test-utils'; +import { applyDatabaseMigrations } from '../../migrations'; +import { markForStitching } from './markForStitching'; +import { DbFinalEntitiesRow, DbRefreshStateRow } from '../../tables'; + +jest.setTimeout(60_000); + +describe('markForStitching', () => { + const databases = TestDatabases.create({ + ids: ['MYSQL_8', 'POSTGRES_13', 'POSTGRES_9', 'SQLITE_3'], + }); + + it.each(databases.eachSupportedId())( + 'marks the right rows in immediate mode %p', + async databaseId => { + const knex = await databases.init(databaseId); + await applyDatabaseMigrations(knex); + + await knex('refresh_state').insert([ + { + entity_id: '1', + entity_ref: 'k:ns/one', + unprocessed_entity: '{}', + processed_entity: '{}', + result_hash: 'old', + errors: '[]', + next_update_at: knex.fn.now(), + last_discovery_at: knex.fn.now(), + }, + { + entity_id: '2', + entity_ref: 'k:ns/two', + unprocessed_entity: '{}', + processed_entity: '{}', + result_hash: 'old', + errors: '[]', + next_update_at: knex.fn.now(), + last_discovery_at: knex.fn.now(), + }, + { + entity_id: '3', + entity_ref: 'k:ns/three', + unprocessed_entity: '{}', + processed_entity: '{}', + result_hash: 'old', + errors: '[]', + next_update_at: knex.fn.now(), + last_discovery_at: knex.fn.now(), + }, + { + entity_id: '4', + entity_ref: 'k:ns/four', + unprocessed_entity: '{}', + processed_entity: '{}', + result_hash: 'old', + errors: '[]', + next_update_at: knex.fn.now(), + last_discovery_at: knex.fn.now(), + }, + ]); + await knex('final_entities').insert([ + { + entity_id: '1', + final_entity: '{}', + hash: 'old', + stitch_ticket: 'old', + }, + { + entity_id: '2', + final_entity: '{}', + hash: 'old', + stitch_ticket: 'old', + }, + { + entity_id: '3', + final_entity: '{}', + hash: 'old', + stitch_ticket: 'old', + }, + { + entity_id: '4', + final_entity: '{}', + hash: 'old', + stitch_ticket: 'old', + }, + ]); + + async function result() { + return knex('refresh_state') + .leftJoin( + 'final_entities', + 'final_entities.entity_id', + 'refresh_state.entity_id', + ) + .select({ + entity_id: 'refresh_state.entity_id', + next_update_at: 'refresh_state.next_update_at', + refresh_state_hash: 'refresh_state.result_hash', + final_entities_hash: 'final_entities.hash', + }) + .orderBy('entity_id', 'asc'); + } + + // Ensure that now() isn't evaluating to the same thing + await new Promise(resolve => setTimeout(resolve, 1100)); + + const original = await result(); + + await markForStitching({ + knex, + strategy: { mode: 'immediate' }, + entityRefs: new Set(), + }); + await expect(result()).resolves.toEqual([ + { + entity_id: '1', + next_update_at: expect.anything(), + refresh_state_hash: 'old', + final_entities_hash: 'old', + }, + { + entity_id: '2', + next_update_at: expect.anything(), + refresh_state_hash: 'old', + final_entities_hash: 'old', + }, + { + entity_id: '3', + next_update_at: expect.anything(), + refresh_state_hash: 'old', + final_entities_hash: 'old', + }, + { + entity_id: '4', + next_update_at: expect.anything(), + refresh_state_hash: 'old', + final_entities_hash: 'old', + }, + ]); + + await markForStitching({ + knex, + strategy: { mode: 'immediate' }, + entityRefs: new Set(['k:ns/one']), + }); + await expect(result()).resolves.toEqual([ + { + entity_id: '1', + next_update_at: expect.anything(), + refresh_state_hash: 'force-stitching', + final_entities_hash: 'force-stitching', + }, + { + entity_id: '2', + next_update_at: expect.anything(), + refresh_state_hash: 'old', + final_entities_hash: 'old', + }, + { + entity_id: '3', + next_update_at: expect.anything(), + refresh_state_hash: 'old', + final_entities_hash: 'old', + }, + { + entity_id: '4', + next_update_at: expect.anything(), + refresh_state_hash: 'old', + final_entities_hash: 'old', + }, + ]); + + await markForStitching({ + knex, + strategy: { mode: 'immediate' }, + entityRefs: ['k:ns/two'], + }); + await expect(result()).resolves.toEqual([ + { + entity_id: '1', + next_update_at: expect.anything(), + refresh_state_hash: 'force-stitching', + final_entities_hash: 'force-stitching', + }, + { + entity_id: '2', + next_update_at: expect.anything(), + refresh_state_hash: 'force-stitching', + final_entities_hash: 'force-stitching', + }, + { + entity_id: '3', + next_update_at: expect.anything(), + refresh_state_hash: 'old', + final_entities_hash: 'old', + }, + { + entity_id: '4', + next_update_at: expect.anything(), + refresh_state_hash: 'old', + final_entities_hash: 'old', + }, + ]); + + await markForStitching({ + knex, + strategy: { mode: 'immediate' }, + entityIds: ['3', '4'], + }); + await expect(result()).resolves.toEqual([ + { + entity_id: '1', + next_update_at: expect.anything(), + refresh_state_hash: 'force-stitching', + final_entities_hash: 'force-stitching', + }, + { + entity_id: '2', + next_update_at: expect.anything(), + refresh_state_hash: 'force-stitching', + final_entities_hash: 'force-stitching', + }, + { + entity_id: '3', + next_update_at: expect.anything(), + refresh_state_hash: 'force-stitching', + final_entities_hash: 'force-stitching', + }, + { + entity_id: '4', + next_update_at: expect.anything(), + refresh_state_hash: 'force-stitching', + final_entities_hash: 'force-stitching', + }, + ]); + + // It overwrites timers + const final = await result(); + for (let i = 0; i < final.length; ++i) { + expect(original[i].next_update_at).not.toEqual(final[i].next_update_at); + } + }, + ); +}); diff --git a/plugins/catalog-backend/src/database/operations/stitcher/markForStitching.ts b/plugins/catalog-backend/src/database/operations/stitcher/markForStitching.ts new file mode 100644 index 0000000000..7ab9bda1c0 --- /dev/null +++ b/plugins/catalog-backend/src/database/operations/stitcher/markForStitching.ts @@ -0,0 +1,82 @@ +/* + * 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 { Knex } from 'knex'; +import splitToChunks from 'lodash/chunk'; +import { StitchingStrategy } from '../../../stitching/types'; +import { DbFinalEntitiesRow, DbRefreshStateRow } from '../../tables'; + +/** + * Marks a number of entities for deferred stitching some time in the near + * future. + * + * @remarks + */ +export async function markForStitching(options: { + knex: Knex | Knex.Transaction; + strategy: StitchingStrategy; + entityRefs?: Iterable; + entityIds?: Iterable; +}): Promise { + // Splitting to chunks just to cover pathological cases that upset the db + const entityRefs = split(options.entityRefs); + const entityIds = split(options.entityIds); + const knex = options.knex; + + for (const chunk of entityRefs) { + await knex + .table('final_entities') + .update({ + hash: 'force-stitching', + }) + .whereIn( + 'entity_id', + knex('refresh_state') + .select('entity_id') + .whereIn('entity_ref', chunk), + ); + await knex + .table('refresh_state') + .update({ + result_hash: 'force-stitching', + next_update_at: knex.fn.now(), + }) + .whereIn('entity_ref', chunk); + } + + for (const chunk of entityIds) { + await knex + .table('final_entities') + .update({ + hash: 'force-stitching', + }) + .whereIn('entity_id', chunk); + await knex + .table('refresh_state') + .update({ + result_hash: 'force-stitching', + next_update_at: knex.fn.now(), + }) + .whereIn('entity_id', chunk); + } +} + +function split(input: Iterable | undefined): string[][] { + if (!input) { + return []; + } + return splitToChunks(Array.isArray(input) ? input : [...input], 200); +} diff --git a/plugins/catalog-backend/src/database/operations/stitcher/performStitching.test.ts b/plugins/catalog-backend/src/database/operations/stitcher/performStitching.test.ts new file mode 100644 index 0000000000..a864cbdef4 --- /dev/null +++ b/plugins/catalog-backend/src/database/operations/stitcher/performStitching.test.ts @@ -0,0 +1,287 @@ +/* + * 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 { getVoidLogger } from '@backstage/backend-common'; +import { TestDatabases } from '@backstage/backend-test-utils'; +import { Entity } from '@backstage/catalog-model'; +import { applyDatabaseMigrations } from '../../migrations'; +import { + DbFinalEntitiesRow, + DbRefreshStateReferencesRow, + DbRefreshStateRow, + DbRelationsRow, + DbSearchRow, +} from '../../tables'; +import { performStitching } from './performStitching'; + +jest.setTimeout(60_000); + +describe('performStitching', () => { + const databases = TestDatabases.create({ + ids: ['MYSQL_8', 'POSTGRES_13', 'POSTGRES_9', 'SQLITE_3'], + }); + const logger = getVoidLogger(); + + it.each(databases.eachSupportedId())( + 'runs the happy path in immediate mode for %p', + async databaseId => { + const knex = await databases.init(databaseId); + await applyDatabaseMigrations(knex); + + let entities: DbFinalEntitiesRow[]; + let entity: Entity; + + await knex('refresh_state').insert([ + { + entity_id: 'my-id', + entity_ref: 'k:ns/n', + unprocessed_entity: JSON.stringify({}), + processed_entity: JSON.stringify({ + apiVersion: 'a', + kind: 'k', + metadata: { + name: 'n', + namespace: 'ns', + }, + spec: { + k: 'v', + }, + }), + errors: '[]', + next_update_at: knex.fn.now(), + last_discovery_at: knex.fn.now(), + }, + ]); + await knex( + 'refresh_state_references', + ).insert([{ source_key: 'a', target_entity_ref: 'k:ns/n' }]); + await knex('relations').insert([ + { + originating_entity_id: 'my-id', + source_entity_ref: 'k:ns/n', + type: 'looksAt', + target_entity_ref: 'k:ns/other', + }, + // handles and ignores duplicates + { + originating_entity_id: 'my-id', + source_entity_ref: 'k:ns/n', + type: 'looksAt', + target_entity_ref: 'k:ns/other', + }, + ]); + + await performStitching({ + knex, + logger, + strategy: { mode: 'immediate' }, + entityRef: 'k:ns/n', + }); + + entities = await knex('final_entities'); + + expect(entities.length).toBe(1); + entity = JSON.parse(entities[0].final_entity!); + expect(entity).toEqual({ + relations: [ + { + type: 'looksAt', + targetRef: 'k:ns/other', + }, + ], + apiVersion: 'a', + kind: 'k', + metadata: { + name: 'n', + namespace: 'ns', + etag: expect.any(String), + uid: 'my-id', + }, + spec: { + k: 'v', + }, + }); + + expect(entity.metadata.etag).toEqual(entities[0].hash); + const last_updated_at = entities[0].last_updated_at; + expect(last_updated_at).not.toBeNull(); + const firstHash = entities[0].hash; + + const search = await knex('search'); + expect(search).toEqual( + expect.arrayContaining([ + { + entity_id: 'my-id', + key: 'relations.looksat', + original_value: 'k:ns/other', + value: 'k:ns/other', + }, + { + entity_id: 'my-id', + key: 'apiversion', + original_value: 'a', + value: 'a', + }, + { + entity_id: 'my-id', + key: 'kind', + original_value: 'k', + value: 'k', + }, + { + entity_id: 'my-id', + key: 'metadata.name', + original_value: 'n', + value: 'n', + }, + { + entity_id: 'my-id', + key: 'metadata.namespace', + original_value: 'ns', + value: 'ns', + }, + { + entity_id: 'my-id', + key: 'metadata.uid', + original_value: 'my-id', + value: 'my-id', + }, + { + entity_id: 'my-id', + key: 'spec.k', + original_value: 'v', + value: 'v', + }, + ]), + ); + + // Re-stitch without any changes + await performStitching({ + knex, + logger, + strategy: { mode: 'immediate' }, + entityRef: 'k:ns/n', + }); + + entities = await knex('final_entities'); + expect(entities.length).toBe(1); + entity = JSON.parse(entities[0].final_entity!); + expect(entities[0].hash).toEqual(firstHash); + expect(entity.metadata.etag).toEqual(firstHash); + + // Now add one more relation and re-stitch + await knex('relations').insert([ + { + originating_entity_id: 'my-id', + source_entity_ref: 'k:ns/n', + type: 'looksAt', + target_entity_ref: 'k:ns/third', + }, + ]); + + await performStitching({ + knex, + logger, + strategy: { mode: 'immediate' }, + entityRef: 'k:ns/n', + }); + + entities = await knex('final_entities'); + + expect(entities.length).toBe(1); + entity = JSON.parse(entities[0].final_entity!); + expect(entity).toEqual({ + relations: expect.arrayContaining([ + { + type: 'looksAt', + targetRef: 'k:ns/other', + }, + { + type: 'looksAt', + targetRef: 'k:ns/third', + }, + ]), + apiVersion: 'a', + kind: 'k', + metadata: { + name: 'n', + namespace: 'ns', + etag: expect.any(String), + uid: 'my-id', + }, + spec: { + k: 'v', + }, + }); + + expect(entities[0].hash).not.toEqual(firstHash); + expect(entities[0].hash).toEqual(entity.metadata.etag); + + expect(await knex('search')).toEqual( + expect.arrayContaining([ + { + entity_id: 'my-id', + key: 'relations.looksat', + original_value: 'k:ns/other', + value: 'k:ns/other', + }, + { + entity_id: 'my-id', + key: 'relations.looksat', + original_value: 'k:ns/third', + value: 'k:ns/third', + }, + { + entity_id: 'my-id', + key: 'apiversion', + original_value: 'a', + value: 'a', + }, + { + entity_id: 'my-id', + key: 'kind', + original_value: 'k', + value: 'k', + }, + { + entity_id: 'my-id', + key: 'metadata.name', + original_value: 'n', + value: 'n', + }, + { + entity_id: 'my-id', + key: 'metadata.namespace', + original_value: 'ns', + value: 'ns', + }, + { + entity_id: 'my-id', + key: 'metadata.uid', + original_value: 'my-id', + value: 'my-id', + }, + { + entity_id: 'my-id', + key: 'spec.k', + original_value: 'v', + value: 'v', + }, + ]), + ); + }, + ); +}); diff --git a/plugins/catalog-backend/src/database/operations/stitcher/performStitching.ts b/plugins/catalog-backend/src/database/operations/stitcher/performStitching.ts new file mode 100644 index 0000000000..bcb112690c --- /dev/null +++ b/plugins/catalog-backend/src/database/operations/stitcher/performStitching.ts @@ -0,0 +1,236 @@ +/* + * 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 { ENTITY_STATUS_CATALOG_PROCESSING_TYPE } from '@backstage/catalog-client'; +import { + ANNOTATION_EDIT_URL, + ANNOTATION_VIEW_URL, + EntityRelation, +} from '@backstage/catalog-model'; +import { AlphaEntity, EntityStatusItem } from '@backstage/catalog-model/alpha'; +import { SerializedError } from '@backstage/errors'; +import { Knex } from 'knex'; +import { v4 as uuid } from 'uuid'; +import { Logger } from 'winston'; +import { StitchingStrategy } from '../../../stitching/types'; +import { + DbFinalEntitiesRow, + DbRefreshStateRow, + DbSearchRow, +} from '../../tables'; +import { buildEntitySearch } from './buildEntitySearch'; +import { BATCH_SIZE, generateStableHash } from './util'; + +// See https://github.com/facebook/react/blob/f0cf832e1d0c8544c36aa8b310960885a11a847c/packages/react-dom-bindings/src/shared/sanitizeURL.js +const scriptProtocolPattern = + // eslint-disable-next-line no-control-regex + /^[\u0000-\u001F ]*j[\r\n\t]*a[\r\n\t]*v[\r\n\t]*a[\r\n\t]*s[\r\n\t]*c[\r\n\t]*r[\r\n\t]*i[\r\n\t]*p[\r\n\t]*t[\r\n\t]*\:/i; + +/** + * Performs the act of stitching - to take all of the various outputs from the + * ingestion process, and stitching them together into the final entity JSON + * shape. + */ +export async function performStitching(options: { + knex: Knex | Knex.Transaction; + logger: Logger; + strategy: StitchingStrategy; + entityRef: string; + stitchTicket?: string; +}): Promise<'changed' | 'unchanged' | 'abandoned'> { + const { knex, logger, entityRef } = options; + const stitchTicket = options.stitchTicket ?? uuid(); + + const entityResult = await knex('refresh_state') + .where({ entity_ref: entityRef }) + .limit(1) + .select('entity_id'); + if (!entityResult.length) { + // Entity does no exist in refresh state table, no stitching required. + return 'abandoned'; + } + + // Insert stitching ticket that will be compared before inserting the final entity. + await knex('final_entities') + .insert({ + entity_id: entityResult[0].entity_id, + hash: '', + stitch_ticket: stitchTicket, + }) + .onConflict('entity_id') + .merge(['stitch_ticket']); + + // Selecting from refresh_state and final_entities should yield exactly + // one row (except in abnormal cases where the stitch was invoked for + // something that didn't exist at all, in which case it's zero rows). + // The join with the temporary incoming_references still gives one row. + const [processedResult, relationsResult] = await Promise.all([ + knex + .with('incoming_references', function incomingReferences(builder) { + return builder + .from('refresh_state_references') + .where({ target_entity_ref: entityRef }) + .count({ count: '*' }); + }) + .select({ + entityId: 'refresh_state.entity_id', + processedEntity: 'refresh_state.processed_entity', + errors: 'refresh_state.errors', + incomingReferenceCount: 'incoming_references.count', + previousHash: 'final_entities.hash', + }) + .from('refresh_state') + .where({ 'refresh_state.entity_ref': entityRef }) + .crossJoin(knex.raw('incoming_references')) + .leftOuterJoin('final_entities', { + 'final_entities.entity_id': 'refresh_state.entity_id', + }), + knex + .distinct({ + relationType: 'type', + relationTarget: 'target_entity_ref', + }) + .from('relations') + .where({ source_entity_ref: entityRef }) + .orderBy('relationType', 'asc') + .orderBy('relationTarget', 'asc'), + ]); + + // If there were no rows returned, it would mean that there was no + // matching row even in the refresh_state. This can happen for example + // if we emit a relation to something that hasn't been ingested yet. + // It's safe to ignore this stitch attempt in that case. + if (!processedResult.length) { + logger.debug( + `Unable to stitch ${entityRef}, item does not exist in refresh state table`, + ); + return 'abandoned'; + } + + const { + entityId, + processedEntity, + errors, + incomingReferenceCount, + previousHash, + } = processedResult[0]; + + // If there was no processed entity in place, the target hasn't been + // through the processing steps yet. It's safe to ignore this stitch + // attempt in that case, since another stitch will be triggered when + // that processing has finished. + if (!processedEntity) { + logger.debug( + `Unable to stitch ${entityRef}, the entity has not yet been processed`, + ); + return 'abandoned'; + } + + // Grab the processed entity and stitch all of the relevant data into + // it + const entity = JSON.parse(processedEntity) as AlphaEntity; + const isOrphan = Number(incomingReferenceCount) === 0; + let statusItems: EntityStatusItem[] = []; + + if (isOrphan) { + logger.debug(`${entityRef} is an orphan`); + entity.metadata.annotations = { + ...entity.metadata.annotations, + ['backstage.io/orphan']: 'true', + }; + } + if (errors) { + const parsedErrors = JSON.parse(errors) as SerializedError[]; + if (Array.isArray(parsedErrors) && parsedErrors.length) { + statusItems = parsedErrors.map(e => ({ + type: ENTITY_STATUS_CATALOG_PROCESSING_TYPE, + level: 'error', + message: `${e.name}: ${e.message}`, + error: e, + })); + } + } + // We opt to do this check here as we otherwise can't guarantee that it will be run after all processors + for (const annotation of [ANNOTATION_VIEW_URL, ANNOTATION_EDIT_URL]) { + const value = entity.metadata.annotations?.[annotation]; + if (typeof value === 'string' && scriptProtocolPattern.test(value)) { + entity.metadata.annotations![annotation] = + 'https://backstage.io/annotation-rejected-for-security-reasons'; + } + } + + // TODO: entityRef is lower case and should be uppercase in the final + // result + entity.relations = relationsResult + .filter(row => row.relationType /* exclude null row, if relevant */) + .map(row => ({ + type: row.relationType!, + targetRef: row.relationTarget!, + })); + if (statusItems.length) { + entity.status = { + ...entity.status, + items: [...(entity.status?.items ?? []), ...statusItems], + }; + } + + // If the output entity was actually not changed, just abort + const hash = generateStableHash(entity); + if (hash === previousHash) { + logger.debug(`Skipped stitching of ${entityRef}, no changes`); + return 'unchanged'; + } + + entity.metadata.uid = entityId; + if (!entity.metadata.etag) { + // If the original data source did not have its own etag handling, + // use the hash as a good-quality etag + entity.metadata.etag = hash; + } + + // This may throw if the entity is invalid, so we call it before + // the final_entities write, even though we may end up not needing + // to write the search index. + const searchEntries = buildEntitySearch(entityId, entity); + + const amountOfRowsChanged = await knex('final_entities') + .update({ + final_entity: JSON.stringify(entity), + hash, + last_updated_at: knex.fn.now(), + }) + .where('entity_id', entityId) + .where('stitch_ticket', stitchTicket) + .onConflict('entity_id') + .merge(['final_entity', 'hash', 'last_updated_at']); + + if (amountOfRowsChanged === 0) { + logger.debug(`Entity ${entityRef} is already stitched, skipping write.`); + return 'abandoned'; + } + + // TODO(freben): Search will probably need a similar safeguard against + // race conditions like the final_entities ticket handling above. + // Otherwise, it can be the case that: + // A writes the entity -> + // B writes the entity -> + // B writes search -> + // A writes search + await knex('search').where({ entity_id: entityId }).delete(); + await knex.batchInsert('search', searchEntries, BATCH_SIZE); + + return 'changed'; +} diff --git a/plugins/catalog-backend/src/stitching/util.ts b/plugins/catalog-backend/src/database/operations/stitcher/util.ts similarity index 100% rename from plugins/catalog-backend/src/stitching/util.ts rename to plugins/catalog-backend/src/database/operations/stitcher/util.ts diff --git a/plugins/catalog-backend/src/database/operations/util/deleteOrphanedEntities.test.ts b/plugins/catalog-backend/src/database/operations/util/deleteOrphanedEntities.test.ts index 243b5db1b9..07ade1c4af 100644 --- a/plugins/catalog-backend/src/database/operations/util/deleteOrphanedEntities.test.ts +++ b/plugins/catalog-backend/src/database/operations/util/deleteOrphanedEntities.test.ts @@ -16,7 +16,7 @@ import { TestDatabaseId, TestDatabases } from '@backstage/backend-test-utils'; import { Knex } from 'knex'; -import * as uuid from 'uuid'; +import { StitchingStrategy } from '../../../stitching/types'; import { applyDatabaseMigrations } from '../../migrations'; import { DbFinalEntitiesRow, @@ -39,14 +39,14 @@ describe('deleteOrphanedEntities', () => { return knex; } - async function run(knex: Knex): Promise { + async function run(knex: Knex, strategy: StitchingStrategy): Promise { let result: number; await knex.transaction( async tx => { // We can't return here, as knex swallows the return type in case the // transaction is rolled back: // https://github.com/knex/knex/blob/e37aeaa31c8ef9c1b07d2e4d3ec6607e557d800d/lib/transaction.js#L136 - result = await deleteOrphanedEntities({ tx }); + result = await deleteOrphanedEntities({ knex: tx, strategy }); }, { // If we explicitly trigger a rollback, don't fail. @@ -58,9 +58,8 @@ describe('deleteOrphanedEntities', () => { async function insertEntity(knex: Knex, ...entityRefs: string[]) { for (const ref of entityRefs) { - const entityId = uuid.v4(); await knex('refresh_state').insert({ - entity_id: entityId, + entity_id: `id-${ref}`, entity_ref: ref, unprocessed_entity: '{}', processed_entity: '{}', @@ -70,7 +69,7 @@ describe('deleteOrphanedEntities', () => { result_hash: 'original', }); await knex('final_entities').insert({ - entity_id: entityId, + entity_id: `id-${ref}`, hash: 'original', stitch_ticket: '', }); @@ -120,7 +119,7 @@ describe('deleteOrphanedEntities', () => { } it.each(databases.eachSupportedId())( - 'works for some mixed paths, %p', + 'works for some mixed paths in immediate mode, %p', async databaseId => { /* In this graph, edges represent refresh state references, not entity relations: @@ -176,18 +175,31 @@ describe('deleteOrphanedEntities', () => { await insertRelation(knex, 'E1', 'E2'); await insertRelation(knex, 'E2', 'E3'); await insertRelation(knex, 'E10', 'E6'); - await expect(run(knex)).resolves.toEqual(5); + await insertRelation(knex, 'E7', 'E6'); + await expect(run(knex, { mode: 'immediate' })).resolves.toEqual(5); await expect(refreshState(knex)).resolves.toEqual([ { entity_ref: 'E1', result_hash: 'original' }, - { entity_ref: 'E2', result_hash: 'orphan-relation-deleted' }, - { entity_ref: 'E7', result_hash: 'original' }, + { + entity_ref: 'E2', + result_hash: 'force-stitching', + }, + { + entity_ref: 'E7', + result_hash: 'force-stitching', + }, { entity_ref: 'E8', result_hash: 'original' }, { entity_ref: 'E9', result_hash: 'original' }, ]); await expect(finalEntities(knex)).resolves.toEqual([ { entity_ref: 'E1', hash: 'original' }, - { entity_ref: 'E2', hash: 'orphan-relation-deleted' }, - { entity_ref: 'E7', hash: 'original' }, + { + entity_ref: 'E2', + hash: 'force-stitching', + }, + { + entity_ref: 'E7', + hash: 'force-stitching', + }, { entity_ref: 'E8', hash: 'original' }, { entity_ref: 'E9', hash: 'original' }, ]); diff --git a/plugins/catalog-backend/src/database/operations/util/deleteOrphanedEntities.ts b/plugins/catalog-backend/src/database/operations/util/deleteOrphanedEntities.ts index eeab85f59e..5e2e46cf89 100644 --- a/plugins/catalog-backend/src/database/operations/util/deleteOrphanedEntities.ts +++ b/plugins/catalog-backend/src/database/operations/util/deleteOrphanedEntities.ts @@ -16,7 +16,9 @@ import { Knex } from 'knex'; import uniq from 'lodash/uniq'; -import { DbFinalEntitiesRow, DbRefreshStateRow } from '../../tables'; +import { StitchingStrategy } from '../../../stitching/types'; +import { DbRefreshStateRow } from '../../tables'; +import { markForStitching } from '../stitcher/markForStitching'; /** * Finds and deletes all orphaned entities, i.e. entities that do not have any @@ -24,15 +26,16 @@ import { DbFinalEntitiesRow, DbRefreshStateRow } from '../../tables'; * that would otherwise become orphaned. */ export async function deleteOrphanedEntities(options: { - tx: Knex.Transaction | Knex; + knex: Knex.Transaction | Knex; + strategy: StitchingStrategy; }): Promise { - const { tx } = options; + const { knex, strategy } = options; let total = 0; // Limit iterations for sanity for (let i = 0; i < 100; ++i) { - const candidates = await tx + const candidates = await knex .with('orphans', ['entity_id', 'entity_ref'], orphans => orphans .from('refresh_state') @@ -72,26 +75,17 @@ export async function deleteOrphanedEntities(options: { total += orphanIds.length; // Delete the orphans themselves - await tx + await knex .table('refresh_state') .delete() .whereIn('entity_id', orphanIds); - // Mark all of things that the orphans had relations to for processing and - // stitching - await tx - .table('final_entities') - .update({ - hash: 'orphan-relation-deleted', - }) - .whereIn('entity_id', orphanRelationIds); - await tx - .table('refresh_state') - .update({ - result_hash: 'orphan-relation-deleted', - next_update_at: tx.fn.now(), - }) - .whereIn('entity_id', orphanRelationIds); + // Mark all of the things that the orphans had relations to for stitching + await markForStitching({ + knex, + strategy, + entityIds: orphanRelationIds, + }); } return total; diff --git a/plugins/catalog-backend/src/database/tables.ts b/plugins/catalog-backend/src/database/tables.ts index e3f3efd1bb..a429dcde8d 100644 --- a/plugins/catalog-backend/src/database/tables.ts +++ b/plugins/catalog-backend/src/database/tables.ts @@ -29,17 +29,88 @@ export type DbLocationsRow = { target: string; }; +/** + * Represents the refresh_state table. + * + * @remarks + * + * Every unique entity ref emitted by a provider or a parent entity becomes a + * row in this table, even before processing has started on it. The actual final + * data, after processing and stitching completes, is instead in the + * final_entities table. + * + * Datetime columns are both string and Date, because different database engines + * return them in different forms on the client side. + */ export type DbRefreshStateRow = { + /** + * The unique ID of the entity. This is different to the entity ref, in that + * it gets regenerated randomly each time a row is added to the table, no + * matter what the original entity data was. + */ entity_id: string; + /** + * The entity string ref (on lowercase kind:namespace/name form) + */ entity_ref: string; + /** + * The JSON of the raw entity, as it was received from the entity provider. + */ unprocessed_entity: string; + /** + * A stable hash of the unprocessed entity, used to detect changed/unchanged + * data for a given entity over time. + */ unprocessed_hash?: string; + /** + * The JSON of the processed entity (if processing has run yet on it). + */ processed_entity?: string; + /** + * A stable hash of the processed entity AND all other emitted things during + * processing, such as relations. + */ result_hash?: string; + /** + * Per-entity cached data on JSON form. This is read and written by processors + * who wish to leverage this feature. + */ cache?: string; + /** + * The next point in time that this entity is due for processing. This + * continuously gets moved forward as items are picked up for processing. + */ next_update_at: string | Date; - last_discovery_at: string | Date; // remove? + /** + * The last time that this entity was emitted by somebody (the entity provider + * or a parent entity). + * + * @remarks + * + * Don't rely on this column more than at most as being loosely informative. + * Its semantics aren't fully settled yet. + */ + last_discovery_at: string | Date; + /** + * A JSON serialized array of errors (if any) encountered during processing. + */ errors?: string; + /** + * A conflict detection/resolution key for the entity. + * + * @remarks + * + * The exact value semantics differs, but may for example be a URL pointing to + * where the entity was sourced from. If a "competing" provider or parent + * entity tries to emit an entity that has the same entity ref but a different + * location key, a conflict is detected (you aren't allowed to "trample" over + * a previously existing entity). + * + * Some providers may choose to emit entities with no location key set at all. + * This is a signal that it's only loosely claimed, and that any other + * competing provider/parent is allowed to overwrite and claim it as theirs + * instead. + */ location_key?: string; }; diff --git a/plugins/catalog-backend/src/database/types.ts b/plugins/catalog-backend/src/database/types.ts index 592d5fe063..56e5f48f14 100644 --- a/plugins/catalog-backend/src/database/types.ts +++ b/plugins/catalog-backend/src/database/types.ts @@ -151,8 +151,6 @@ export interface ProcessingDatabase { txOpaque: Transaction, options: ListParentsOptions, ): Promise; - - deleteOrphanedEntities(txOpaque: Transaction): Promise; } /** diff --git a/plugins/catalog-backend/src/processing/DefaultCatalogProcessingEngine.test.ts b/plugins/catalog-backend/src/processing/DefaultCatalogProcessingEngine.test.ts index 00235ef601..fba5e387a9 100644 --- a/plugins/catalog-backend/src/processing/DefaultCatalogProcessingEngine.test.ts +++ b/plugins/catalog-backend/src/processing/DefaultCatalogProcessingEngine.test.ts @@ -21,7 +21,7 @@ import waitForExpect from 'wait-for-expect'; import { DefaultProcessingDatabase } from '../database/DefaultProcessingDatabase'; import { DefaultCatalogProcessingEngine } from './DefaultCatalogProcessingEngine'; import { CatalogProcessingOrchestrator } from './types'; -import { Stitcher } from '../stitching/Stitcher'; +import { Stitcher } from '../stitching/types'; import { ConfigReader } from '@backstage/config'; describe('DefaultCatalogProcessingEngine', () => { @@ -66,6 +66,7 @@ describe('DefaultCatalogProcessingEngine', () => { config: new ConfigReader({}), logger: getVoidLogger(), processingDatabase: db, + knex: {} as any, orchestrator: orchestrator, stitcher: stitcher, createHash: () => hash, @@ -133,6 +134,7 @@ describe('DefaultCatalogProcessingEngine', () => { config: new ConfigReader({}), logger: getVoidLogger(), processingDatabase: db, + knex: {} as any, orchestrator: orchestrator, stitcher: stitcher, createHash: () => hash, @@ -216,6 +218,7 @@ describe('DefaultCatalogProcessingEngine', () => { config: new ConfigReader({}), logger: getVoidLogger(), processingDatabase: db, + knex: {} as any, orchestrator: orchestrator, stitcher: stitcher, createHash: () => hash, @@ -292,6 +295,7 @@ describe('DefaultCatalogProcessingEngine', () => { config: new ConfigReader({}), logger: getVoidLogger(), processingDatabase: db, + knex: {} as any, orchestrator: orchestrator, stitcher: stitcher, createHash: () => hash, @@ -350,6 +354,7 @@ describe('DefaultCatalogProcessingEngine', () => { config: new ConfigReader({}), logger: getVoidLogger(), processingDatabase: db, + knex: {} as any, orchestrator: orchestrator, stitcher: stitcher, createHash: () => hash, @@ -450,10 +455,10 @@ describe('DefaultCatalogProcessingEngine', () => { await waitForExpect(() => { expect(stitcher.stitch).toHaveBeenCalledTimes(2); }); - expect([...stitcher.stitch.mock.calls[0][0]]).toEqual( + expect([...stitcher.stitch.mock.calls[0][0].entityRefs!]).toEqual( expect.arrayContaining(['k:ns/me', 'k:ns/other1', 'k:ns/other2']), ); - expect([...stitcher.stitch.mock.calls[1][0]]).toEqual( + expect([...stitcher.stitch.mock.calls[1][0].entityRefs!]).toEqual( expect.arrayContaining(['k:ns/me', 'k:ns/other1', 'k:ns/other3']), ); await engine.stop(); @@ -464,6 +469,7 @@ describe('DefaultCatalogProcessingEngine', () => { config: new ConfigReader({}), logger: getVoidLogger(), processingDatabase: db, + knex: {} as any, orchestrator: orchestrator, stitcher: stitcher, createHash: () => hash, @@ -535,7 +541,7 @@ describe('DefaultCatalogProcessingEngine', () => { await waitForExpect(() => { expect(stitcher.stitch).toHaveBeenCalledTimes(1); }); - expect([...stitcher.stitch.mock.calls[0][0]]).toEqual( + expect([...stitcher.stitch.mock.calls[0][0].entityRefs!]).toEqual( expect.arrayContaining(['k:ns/me']), ); await engine.stop(); @@ -546,6 +552,7 @@ describe('DefaultCatalogProcessingEngine', () => { config: new ConfigReader({}), logger: getVoidLogger(), processingDatabase: db, + knex: {} as any, orchestrator: orchestrator, stitcher: stitcher, createHash: () => hash, @@ -622,7 +629,7 @@ describe('DefaultCatalogProcessingEngine', () => { await waitForExpect(() => { expect(stitcher.stitch).toHaveBeenCalledTimes(1); }); - expect([...stitcher.stitch.mock.calls[0][0]]).toEqual( + expect([...stitcher.stitch.mock.calls[0][0].entityRefs!]).toEqual( expect.arrayContaining(['k:ns/me', 'k:ns/other2']), ); await engine.stop(); @@ -633,6 +640,7 @@ describe('DefaultCatalogProcessingEngine', () => { config: new ConfigReader({}), logger: getVoidLogger(), processingDatabase: db, + knex: {} as any, orchestrator: orchestrator, stitcher: stitcher, createHash: () => hash, @@ -699,7 +707,7 @@ describe('DefaultCatalogProcessingEngine', () => { await waitForExpect(() => { expect(stitcher.stitch).toHaveBeenCalledTimes(1); }); - expect([...stitcher.stitch.mock.calls[0][0]]).toEqual( + expect([...stitcher.stitch.mock.calls[0][0].entityRefs!]).toEqual( expect.arrayContaining(['k:ns/me', 'k:ns/other2']), ); await engine.stop(); diff --git a/plugins/catalog-backend/src/processing/DefaultCatalogProcessingEngine.ts b/plugins/catalog-backend/src/processing/DefaultCatalogProcessingEngine.ts index bed1fe6f50..72f92b9b40 100644 --- a/plugins/catalog-backend/src/processing/DefaultCatalogProcessingEngine.ts +++ b/plugins/catalog-backend/src/processing/DefaultCatalogProcessingEngine.ts @@ -22,16 +22,13 @@ import { import { assertError, serializeError, stringifyError } from '@backstage/errors'; import { Hash } from 'crypto'; import stableStringify from 'fast-json-stable-stringify'; +import { Knex } from 'knex'; import { Logger } from 'winston'; import { metrics, trace } from '@opentelemetry/api'; import { ProcessingDatabase, RefreshStateItem } from '../database/types'; import { createCounterMetric, createSummaryMetric } from '../util/metrics'; -import { - CatalogProcessingEngine, - CatalogProcessingOrchestrator, - EntityProcessingResult, -} from './types'; -import { Stitcher } from '../stitching/Stitcher'; +import { CatalogProcessingOrchestrator, EntityProcessingResult } from './types'; +import { Stitcher } from '../stitching/types'; import { startTaskPipeline } from './TaskPipeline'; import { PluginTaskScheduler } from '@backstage/backend-tasks'; import { Config } from '@backstage/config'; @@ -40,6 +37,7 @@ import { TRACER_ID, withActiveSpan, } from '../util/opentelemetry'; +import { deleteOrphanedEntities } from '../database/operations/util/deleteOrphanedEntities'; const CACHE_TTL = 5; @@ -47,10 +45,17 @@ const tracer = trace.getTracer(TRACER_ID); export type ProgressTracker = ReturnType; -export class DefaultCatalogProcessingEngine implements CatalogProcessingEngine { +// NOTE(freben): Perhaps surprisingly, this class does not implement the +// CatalogProcessingEngine type. That type is externally visible and its name is +// the way it is for historic reasons. This class has no particular reason to +// implement that precise interface; nowadays there are several different +// engines "hiding" behind the CatalogProcessingEngine interface, of which this +// is just one. +export class DefaultCatalogProcessingEngine { private readonly config: Config; private readonly scheduler?: PluginTaskScheduler; private readonly logger: Logger; + private readonly knex: Knex; private readonly processingDatabase: ProcessingDatabase; private readonly orchestrator: CatalogProcessingOrchestrator; private readonly stitcher: Stitcher; @@ -69,6 +74,7 @@ export class DefaultCatalogProcessingEngine implements CatalogProcessingEngine { config: Config; scheduler?: PluginTaskScheduler; logger: Logger; + knex: Knex; processingDatabase: ProcessingDatabase; orchestrator: CatalogProcessingOrchestrator; stitcher: Stitcher; @@ -84,6 +90,7 @@ export class DefaultCatalogProcessingEngine implements CatalogProcessingEngine { this.config = options.config; this.scheduler = options.scheduler; this.logger = options.logger; + this.knex = options.knex; this.processingDatabase = options.processingDatabase; this.orchestrator = options.orchestrator; this.stitcher = options.stitcher; @@ -255,9 +262,11 @@ export class DefaultCatalogProcessingEngine implements CatalogProcessingEngine { resultHash, }); }); - await this.stitcher.stitch( - new Set([stringifyEntityRef(unprocessedEntity)]), - ); + + await this.stitcher.stitch({ + entityRefs: [stringifyEntityRef(unprocessedEntity)], + }); + track.markSuccessfulWithErrors(); return; } @@ -305,9 +314,11 @@ export class DefaultCatalogProcessingEngine implements CatalogProcessingEngine { } }); - await this.stitcher.stitch(setOfThingsToStitch); + await this.stitcher.stitch({ + entityRefs: setOfThingsToStitch, + }); - track.markSuccessfulWithChanges(setOfThingsToStitch.size); + track.markSuccessfulWithChanges(); } catch (error) { assertError(error); track.markFailed(error); @@ -318,20 +329,21 @@ export class DefaultCatalogProcessingEngine implements CatalogProcessingEngine { } private startOrphanCleanup(): () => void { - const strategy = + const orphanStrategy = this.config.getOptionalString('catalog.orphanStrategy') ?? 'keep'; - if (strategy !== 'delete') { + if (orphanStrategy !== 'delete') { return () => {}; } const runOnce = async () => { try { - await this.processingDatabase.transaction(async tx => { - const n = await this.processingDatabase.deleteOrphanedEntities(tx); - if (n > 0) { - this.logger.info(`Deleted ${n} orphaned entities`); - } + const n = await deleteOrphanedEntities({ + knex: this.knex, + strategy: { mode: 'immediate' }, }); + if (n > 0) { + this.logger.info(`Deleted ${n} orphaned entities`); + } } catch (error) { this.logger.warn(`Failed to delete orphaned entities`, error); } @@ -363,10 +375,6 @@ export class DefaultCatalogProcessingEngine implements CatalogProcessingEngine { // Helps wrap the timing and logging behaviors function progressTracker() { // prom-client metrics are deprecated in favour of OpenTelemetry metrics. - const promStitchedEntities = createCounterMetric({ - name: 'catalog_stitched_entities_count', - help: 'Amount of entities stitched. DEPRECATED, use OpenTelemetry metrics instead', - }); const promProcessedEntities = createCounterMetric({ name: 'catalog_processed_entities_count', help: 'Amount of entities processed, DEPRECATED, use OpenTelemetry metrics instead', @@ -388,11 +396,6 @@ function progressTracker() { }); const meter = metrics.getMeter('default'); - const stitchedEntities = meter.createCounter( - 'catalog.stitched.entities.count', - { description: 'Amount of entities stitched' }, - ); - const processedEntities = meter.createCounter( 'catalog.processed.entities.count', { description: 'Amount of entities processed' }, @@ -464,13 +467,11 @@ function progressTracker() { processedEntities.add(1, { result: 'errors' }); } - function markSuccessfulWithChanges(stitchedCount: number) { + function markSuccessfulWithChanges() { endOverallTimer({ result: 'changed' }); - promStitchedEntities.inc(stitchedCount); promProcessedEntities.inc({ result: 'changed' }, 1); processingDuration.record(endTime(), { result: 'changed' }); - stitchedEntities.add(stitchedCount); processedEntities.add(1, { result: 'changed' }); } diff --git a/plugins/catalog-backend/src/processing/types.ts b/plugins/catalog-backend/src/processing/types.ts index c0d0e5db0d..002747d4c4 100644 --- a/plugins/catalog-backend/src/processing/types.ts +++ b/plugins/catalog-backend/src/processing/types.ts @@ -64,8 +64,8 @@ export interface CatalogProcessingOrchestrator { } /** - * Represents the engine that drives the processing loops. Some backend - * instances may choose to not call start, if they focus only on API + * Represents the engine that drives the processing and stitching loops. Some + * backend instances may choose to not call start, if they focus only on API * interactions. * * @public diff --git a/plugins/catalog-backend/src/service/CatalogBuilder.ts b/plugins/catalog-backend/src/service/CatalogBuilder.ts index 531bb91dd2..c12178e888 100644 --- a/plugins/catalog-backend/src/service/CatalogBuilder.ts +++ b/plugins/catalog-backend/src/service/CatalogBuilder.ts @@ -65,7 +65,7 @@ import { DefaultCatalogProcessingEngine } from '../processing/DefaultCatalogProc import { DefaultLocationService } from './DefaultLocationService'; import { DefaultEntitiesCatalog } from './DefaultEntitiesCatalog'; import { DefaultCatalogProcessingOrchestrator } from '../processing/DefaultCatalogProcessingOrchestrator'; -import { Stitcher } from '../stitching/Stitcher'; +import { DefaultStitcher } from '../stitching/DefaultStitcher'; import { createRandomProcessingInterval, ProcessingIntervalFunction, @@ -449,6 +449,11 @@ export class CatalogBuilder { await applyDatabaseMigrations(dbClient); } + const stitcher = DefaultStitcher.fromConfig(config, { + knex: dbClient, + logger, + }); + const processingDatabase = new DefaultProcessingDatabase({ database: dbClient, logger, @@ -474,7 +479,6 @@ export class CatalogBuilder { policy, legacySingleProcessorValidation: this.legacySingleProcessorValidation, }); - const stitcher = new Stitcher(dbClient, logger); const unauthorizedEntitiesCatalog = new DefaultEntitiesCatalog({ database: dbClient, logger, @@ -535,6 +539,7 @@ export class CatalogBuilder { config, scheduler, logger, + knex: dbClient, processingDatabase, orchestrator, stitcher, @@ -572,7 +577,16 @@ export class CatalogBuilder { await connectEntityProviders(providerDatabase, entityProviders); return { - processingEngine, + processingEngine: { + async start() { + await processingEngine.start(); + await stitcher.start(); + }, + async stop() { + await processingEngine.stop(); + await stitcher.stop(); + }, + }, router, }; } diff --git a/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.test.ts b/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.test.ts index 4f011813e6..fde3408c4b 100644 --- a/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.test.ts +++ b/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.test.ts @@ -30,10 +30,10 @@ import { DbRefreshStateRow, DbSearchRow, } from '../database/tables'; -import { Stitcher } from '../stitching/Stitcher'; -import { buildEntitySearch } from '../stitching/buildEntitySearch'; +import { Stitcher } from '../stitching/types'; import { DefaultEntitiesCatalog } from './DefaultEntitiesCatalog'; import { EntitiesRequest } from '../catalog/types'; +import { buildEntitySearch } from '../database/operations/stitcher/buildEntitySearch'; jest.setTimeout(60_000); @@ -1684,9 +1684,9 @@ describe('DefaultEntitiesCatalog', () => { { entity_ref: 'k:default/unrelated1', result_hash: 'not-changed' }, { entity_ref: 'k:default/unrelated2', result_hash: 'not-changed' }, ]); - expect(stitch).toHaveBeenCalledWith( - new Set(['k:default/unrelated1', 'k:default/unrelated2']), - ); + expect(stitch).toHaveBeenCalledWith({ + entityRefs: new Set(['k:default/unrelated1', 'k:default/unrelated2']), + }); }, ); }); diff --git a/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.ts b/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.ts index c328c83823..24f0432419 100644 --- a/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.ts +++ b/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.ts @@ -49,8 +49,7 @@ import { DbRelationsRow, DbSearchRow, } from '../database/tables'; - -import { Stitcher } from '../stitching/Stitcher'; +import { Stitcher } from '../stitching/types'; import { isQueryEntitiesCursorRequest, @@ -606,7 +605,9 @@ export class DefaultEntitiesCatalog implements EntitiesCatalog { .where('entity_id', uid) .delete(); - await this.stitcher.stitch(new Set(relationPeers.map(p => p.ref))); + await this.stitcher.stitch({ + entityRefs: new Set(relationPeers.map(p => p.ref)), + }); } async entityAncestry(rootRef: string): Promise { diff --git a/plugins/catalog-backend/src/service/DefaultRefreshService.test.ts b/plugins/catalog-backend/src/service/DefaultRefreshService.test.ts index 76284ebbfd..5b29bb34d5 100644 --- a/plugins/catalog-backend/src/service/DefaultRefreshService.test.ts +++ b/plugins/catalog-backend/src/service/DefaultRefreshService.test.ts @@ -31,9 +31,9 @@ import { import { ProcessingDatabase } from '../database/types'; import { DefaultCatalogProcessingEngine } from '../processing/DefaultCatalogProcessingEngine'; import { EntityProcessingRequest } from '../processing/types'; -import { Stitcher } from '../stitching/Stitcher'; import { DefaultRefreshService } from './DefaultRefreshService'; import { ConfigReader } from '@backstage/config'; +import { DefaultStitcher } from '../stitching/DefaultStitcher'; jest.setTimeout(60_000); @@ -109,10 +109,16 @@ describe('DefaultRefreshService', () => { } } + const stitcher = DefaultStitcher.fromConfig(new ConfigReader({}), { + knex, + logger: defaultLogger, + }); const engine = new DefaultCatalogProcessingEngine({ config: new ConfigReader({}), logger: defaultLogger, processingDatabase: db, + knex: knex, + stitcher: stitcher, orchestrator: { async process(request: EntityProcessingRequest) { const entityRef = stringifyEntityRef(request.entity); @@ -151,7 +157,6 @@ describe('DefaultRefreshService', () => { }; }, }, - stitcher: new Stitcher(knex, defaultLogger), createHash: () => createHash('sha1'), pollingIntervalMs: 50, }); diff --git a/plugins/catalog-backend/src/stitching/Stitcher.test.ts b/plugins/catalog-backend/src/stitching/DefaultStitcher.test.ts similarity index 95% rename from plugins/catalog-backend/src/stitching/Stitcher.test.ts rename to plugins/catalog-backend/src/stitching/DefaultStitcher.test.ts index 1efcb01a3c..5b33fc424c 100644 --- a/plugins/catalog-backend/src/stitching/Stitcher.test.ts +++ b/plugins/catalog-backend/src/stitching/DefaultStitcher.test.ts @@ -25,7 +25,7 @@ import { DbRelationsRow, DbSearchRow, } from '../database/tables'; -import { Stitcher } from './Stitcher'; +import { DefaultStitcher } from './DefaultStitcher'; jest.setTimeout(60_000); @@ -41,7 +41,11 @@ describe('Stitcher', () => { const db = await databases.init(databaseId); await applyDatabaseMigrations(db); - const stitcher = new Stitcher(db, logger); + const stitcher = new DefaultStitcher({ + knex: db, + logger, + strategy: { mode: 'immediate' }, + }); let entities: DbFinalEntitiesRow[]; let entity: Entity; @@ -85,7 +89,7 @@ describe('Stitcher', () => { }, ]); - await stitcher.stitch(new Set(['k:ns/n'])); + await stitcher.stitch({ entityRefs: ['k:ns/n'] }); entities = await db('final_entities'); @@ -165,7 +169,7 @@ describe('Stitcher', () => { ); // Re-stitch without any changes - await stitcher.stitch(new Set(['k:ns/n'])); + await stitcher.stitch({ entityRefs: ['k:ns/n'] }); entities = await db('final_entities'); expect(entities.length).toBe(1); @@ -183,7 +187,7 @@ describe('Stitcher', () => { }, ]); - await stitcher.stitch(new Set(['k:ns/n'])); + await stitcher.stitch({ entityRefs: ['k:ns/n'] }); entities = await db('final_entities'); diff --git a/plugins/catalog-backend/src/stitching/DefaultStitcher.ts b/plugins/catalog-backend/src/stitching/DefaultStitcher.ts new file mode 100644 index 0000000000..095d80ad83 --- /dev/null +++ b/plugins/catalog-backend/src/stitching/DefaultStitcher.ts @@ -0,0 +1,124 @@ +/* + * 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 { Config } from '@backstage/config'; +import { Knex } from 'knex'; +import splitToChunks from 'lodash/chunk'; +import { DateTime } from 'luxon'; +import { Logger } from 'winston'; +import { performStitching } from '../database/operations/stitcher/performStitching'; +import { DbRefreshStateRow } from '../database/tables'; +import { progressTracker } from './progressTracker'; +import { Stitcher, StitchingStrategy } from './types'; + +type StitchProgressTracker = ReturnType; + +/** + * Performs the act of stitching - to take all of the various outputs from the + * ingestion process, and stitching them together into the final entity JSON + * shape. + */ +export class DefaultStitcher implements Stitcher { + private readonly knex: Knex; + private readonly logger: Logger; + private readonly strategy: StitchingStrategy; + private readonly tracker: StitchProgressTracker; + + static fromConfig( + _config: Config, + options: { + knex: Knex; + logger: Logger; + }, + ): DefaultStitcher { + return new DefaultStitcher({ + knex: options.knex, + logger: options.logger, + strategy: { mode: 'immediate' }, + }); + } + + constructor(options: { + knex: Knex; + logger: Logger; + strategy: StitchingStrategy; + }) { + this.knex = options.knex; + this.logger = options.logger; + this.strategy = options.strategy; + this.tracker = progressTracker(options.knex, options.logger); + } + + async stitch(options: { + entityRefs?: Iterable; + entityIds?: Iterable; + }) { + const { entityRefs, entityIds } = options; + + if (entityRefs) { + for (const entityRef of entityRefs) { + await this.#stitchOne({ entityRef }); + } + } + + if (entityIds) { + const chunks = splitToChunks( + Array.isArray(entityIds) ? entityIds : [...entityIds], + 100, + ); + for (const chunk of chunks) { + const rows = await this.knex('refresh_state') + .select('entity_ref') + .whereIn('entity_id', chunk); + for (const row of rows) { + await this.#stitchOne({ entityRef: row.entity_ref }); + } + } + } + } + + async start() { + // Only called immediately for now + } + + async stop() { + // Only called immediately for now + } + + async #stitchOne(options: { + entityRef: string; + stitchTicket?: string; + stitchRequestedAt?: DateTime; + }) { + const track = this.tracker.stitchStart({ + entityRef: options.entityRef, + stitchRequestedAt: options.stitchRequestedAt, + }); + + try { + const result = await performStitching({ + knex: this.knex, + logger: this.logger, + strategy: this.strategy, + entityRef: options.entityRef, + stitchTicket: options.stitchTicket, + }); + track.markComplete(result); + } catch (error) { + track.markFailed(error); + } + } +} diff --git a/plugins/catalog-backend/src/stitching/Stitcher.ts b/plugins/catalog-backend/src/stitching/Stitcher.ts deleted file mode 100644 index 38d0fd263f..0000000000 --- a/plugins/catalog-backend/src/stitching/Stitcher.ts +++ /dev/null @@ -1,250 +0,0 @@ -/* - * 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 { ENTITY_STATUS_CATALOG_PROCESSING_TYPE } from '@backstage/catalog-client'; -import { AlphaEntity, EntityStatusItem } from '@backstage/catalog-model/alpha'; -import { - ANNOTATION_EDIT_URL, - ANNOTATION_VIEW_URL, - EntityRelation, -} from '@backstage/catalog-model'; -import { SerializedError, stringifyError } from '@backstage/errors'; -import { Knex } from 'knex'; -import { v4 as uuid } from 'uuid'; -import { Logger } from 'winston'; -import { - DbFinalEntitiesRow, - DbRefreshStateRow, - DbSearchRow, -} from '../database/tables'; -import { buildEntitySearch } from './buildEntitySearch'; -import { BATCH_SIZE, generateStableHash } from './util'; - -// See https://github.com/facebook/react/blob/f0cf832e1d0c8544c36aa8b310960885a11a847c/packages/react-dom-bindings/src/shared/sanitizeURL.js -const scriptProtocolPattern = - // eslint-disable-next-line no-control-regex - /^[\u0000-\u001F ]*j[\r\n\t]*a[\r\n\t]*v[\r\n\t]*a[\r\n\t]*s[\r\n\t]*c[\r\n\t]*r[\r\n\t]*i[\r\n\t]*p[\r\n\t]*t[\r\n\t]*\:/i; - -/** - * Performs the act of stitching - to take all of the various outputs from the - * ingestion process, and stitching them together into the final entity JSON - * shape. - */ -export class Stitcher { - constructor( - private readonly database: Knex, - private readonly logger: Logger, - ) {} - - async stitch(entityRefs: Set) { - for (const entityRef of entityRefs) { - try { - await this.stitchOne(entityRef); - } catch (error) { - this.logger.error( - `Failed to stitch ${entityRef}, ${stringifyError(error)}`, - ); - } - } - } - - private async stitchOne(entityRef: string): Promise { - const entityResult = await this.database('refresh_state') - .where({ entity_ref: entityRef }) - .limit(1) - .select('entity_id'); - if (!entityResult.length) { - // Entity does no exist in refresh state table, no stitching required. - return; - } - - // Insert stitching ticket that will be compared before inserting the final entity. - const ticket = uuid(); - await this.database('final_entities') - .insert({ - entity_id: entityResult[0].entity_id, - hash: '', - stitch_ticket: ticket, - }) - .onConflict('entity_id') - .merge(['stitch_ticket']); - - // Selecting from refresh_state and final_entities should yield exactly - // one row (except in abnormal cases where the stitch was invoked for - // something that didn't exist at all, in which case it's zero rows). - // The join with the temporary incoming_references still gives one row. - const [processedResult, relationsResult] = await Promise.all([ - this.database - .with('incoming_references', function incomingReferences(builder) { - return builder - .from('refresh_state_references') - .where({ target_entity_ref: entityRef }) - .count({ count: '*' }); - }) - .select({ - entityId: 'refresh_state.entity_id', - processedEntity: 'refresh_state.processed_entity', - errors: 'refresh_state.errors', - incomingReferenceCount: 'incoming_references.count', - previousHash: 'final_entities.hash', - }) - .from('refresh_state') - .where({ 'refresh_state.entity_ref': entityRef }) - .crossJoin(this.database.raw('incoming_references')) - .leftOuterJoin('final_entities', { - 'final_entities.entity_id': 'refresh_state.entity_id', - }), - this.database - .distinct({ - relationType: 'type', - relationTarget: 'target_entity_ref', - }) - .from('relations') - .where({ source_entity_ref: entityRef }) - .orderBy('relationType', 'asc') - .orderBy('relationTarget', 'asc'), - ]); - - // If there were no rows returned, it would mean that there was no - // matching row even in the refresh_state. This can happen for example - // if we emit a relation to something that hasn't been ingested yet. - // It's safe to ignore this stitch attempt in that case. - if (!processedResult.length) { - this.logger.error( - `Unable to stitch ${entityRef}, item does not exist in refresh state table`, - ); - return; - } - - const { - entityId, - processedEntity, - errors, - incomingReferenceCount, - previousHash, - } = processedResult[0]; - - // If there was no processed entity in place, the target hasn't been - // through the processing steps yet. It's safe to ignore this stitch - // attempt in that case, since another stitch will be triggered when - // that processing has finished. - if (!processedEntity) { - this.logger.debug( - `Unable to stitch ${entityRef}, the entity has not yet been processed`, - ); - return; - } - - // Grab the processed entity and stitch all of the relevant data into - // it - const entity = JSON.parse(processedEntity) as AlphaEntity; - const isOrphan = Number(incomingReferenceCount) === 0; - let statusItems: EntityStatusItem[] = []; - - if (isOrphan) { - this.logger.debug(`${entityRef} is an orphan`); - entity.metadata.annotations = { - ...entity.metadata.annotations, - ['backstage.io/orphan']: 'true', - }; - } - if (errors) { - const parsedErrors = JSON.parse(errors) as SerializedError[]; - if (Array.isArray(parsedErrors) && parsedErrors.length) { - statusItems = parsedErrors.map(e => ({ - type: ENTITY_STATUS_CATALOG_PROCESSING_TYPE, - level: 'error', - message: `${e.name}: ${e.message}`, - error: e, - })); - } - } - // We opt to do this check here as we otherwise can't guarantee that it will be run after all processors - for (const annotation of [ANNOTATION_VIEW_URL, ANNOTATION_EDIT_URL]) { - const value = entity.metadata.annotations?.[annotation]; - if (typeof value === 'string' && scriptProtocolPattern.test(value)) { - entity.metadata.annotations![annotation] = - 'https://backstage.io/annotation-rejected-for-security-reasons'; - } - } - - // TODO: entityRef is lower case and should be uppercase in the final - // result - entity.relations = relationsResult - .filter(row => row.relationType /* exclude null row, if relevant */) - .map(row => ({ - type: row.relationType!, - targetRef: row.relationTarget!, - })); - if (statusItems.length) { - entity.status = { - ...entity.status, - items: [...(entity.status?.items ?? []), ...statusItems], - }; - } - - // If the output entity was actually not changed, just abort - const hash = generateStableHash(entity); - if (hash === previousHash) { - this.logger.debug(`Skipped stitching of ${entityRef}, no changes`); - return; - } - - entity.metadata.uid = entityId; - if (!entity.metadata.etag) { - // If the original data source did not have its own etag handling, - // use the hash as a good-quality etag - entity.metadata.etag = hash; - } - - // This may throw if the entity is invalid, so we call it before - // the final_entities write, even though we may end up not needing - // to write the search index. - const searchEntries = buildEntitySearch(entityId, entity); - - const amountOfRowsChanged = await this.database( - 'final_entities', - ) - .update({ - final_entity: JSON.stringify(entity), - hash, - last_updated_at: this.database.fn.now(), - }) - .where('entity_id', entityId) - .where('stitch_ticket', ticket) - .onConflict('entity_id') - .merge(['final_entity', 'hash', 'last_updated_at']); - - if (amountOfRowsChanged === 0) { - this.logger.debug( - `Entity ${entityRef} is already processed, skipping write.`, - ); - return; - } - - // TODO(freben): Search will probably need a similar safeguard against - // race conditions like the final_entities ticket handling above. - // Otherwise, it can be the case that: - // A writes the entity -> - // B writes the entity -> - // B writes search -> - // A writes search - await this.database('search') - .where({ entity_id: entityId }) - .delete(); - await this.database.batchInsert('search', searchEntries, BATCH_SIZE); - } -} diff --git a/plugins/catalog-backend/src/stitching/progressTracker.ts b/plugins/catalog-backend/src/stitching/progressTracker.ts new file mode 100644 index 0000000000..e8e08dbc54 --- /dev/null +++ b/plugins/catalog-backend/src/stitching/progressTracker.ts @@ -0,0 +1,84 @@ +/* + * 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 { stringifyError } from '@backstage/errors'; +import { metrics } from '@opentelemetry/api'; +import { Knex } from 'knex'; +import { DateTime } from 'luxon'; +import { Logger } from 'winston'; +import { createCounterMetric } from '../util/metrics'; + +// Helps wrap the timing and logging behaviors +export function progressTracker(_knex: Knex, logger: Logger) { + // prom-client metrics are deprecated in favour of OpenTelemetry metrics. + const promStitchedEntities = createCounterMetric({ + name: 'catalog_stitched_entities_count', + help: 'Amount of entities stitched. DEPRECATED, use OpenTelemetry metrics instead', + }); + + const meter = metrics.getMeter('default'); + + const stitchedEntities = meter.createCounter( + 'catalog.stitched.entities.count', + { + description: 'Amount of entities stitched', + }, + ); + + const stitchingDuration = meter.createHistogram( + 'catalog.stitching.duration', + { + description: 'Time spent executing the full stitching flow', + unit: 'seconds', + }, + ); + + function stitchStart(item: { + entityRef: string; + stitchRequestedAt?: DateTime; + }) { + logger.debug(`Stitching ${item.entityRef}`); + + const startTime = process.hrtime(); + + function endTime() { + const delta = process.hrtime(startTime); + return delta[0] + delta[1] / 1e9; + } + + function markComplete(result: string) { + promStitchedEntities.inc(1); + stitchedEntities.add(1, { result }); + stitchingDuration.record(endTime(), { result }); + } + + function markFailed(error: Error) { + promStitchedEntities.inc(1); + stitchedEntities.add(1, { result: 'error' }); + stitchingDuration.record(endTime(), { result: 'error' }); + logger.error( + `Failed to stitch ${item.entityRef}, ${stringifyError(error)}`, + ); + } + + return { + markComplete, + markFailed, + }; + } + + return { stitchStart }; +} diff --git a/plugins/catalog-backend/src/stitching/types.ts b/plugins/catalog-backend/src/stitching/types.ts new file mode 100644 index 0000000000..5f32a85b1f --- /dev/null +++ b/plugins/catalog-backend/src/stitching/types.ts @@ -0,0 +1,40 @@ +/* + * 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. + */ + +/** + * Performs the act of stitching - to take all of the various outputs from the + * ingestion process, and stitching them together into the final entity JSON + * shape. + */ +export interface Stitcher { + stitch(options: { + entityRefs?: Iterable; + entityIds?: Iterable; + }): Promise; +} + +/** + * The strategies supported by the stitching process, in terms of when to + * perform stitching. + * + * @remarks + * + * In immediate mode, stitching happens "in-band" (blocking) immediately when + * each processing task finishes. + */ +export type StitchingStrategy = { + mode: 'immediate'; +}; diff --git a/plugins/catalog-backend/src/tests/integration.test.ts b/plugins/catalog-backend/src/tests/integration.test.ts index e7f983f51f..8aeb95f49b 100644 --- a/plugins/catalog-backend/src/tests/integration.test.ts +++ b/plugins/catalog-backend/src/tests/integration.test.ts @@ -53,7 +53,7 @@ import { CatalogProcessingEngine } from '../processing/types'; import { DefaultEntitiesCatalog } from '../service/DefaultEntitiesCatalog'; import { DefaultRefreshService } from '../service/DefaultRefreshService'; import { RefreshOptions, RefreshService } from '../service/types'; -import { Stitcher } from '../stitching/Stitcher'; +import { DefaultStitcher } from '../stitching/DefaultStitcher'; const voidLogger = getVoidLogger(); @@ -268,7 +268,7 @@ class TestHarness { policy: EntityPolicies.allOf([]), legacySingleProcessorValidation: false, }); - const stitcher = new Stitcher(db, logger); + const stitcher = DefaultStitcher.fromConfig(config, { knex: db, logger }); const catalog = new DefaultEntitiesCatalog({ database: db, logger, @@ -282,6 +282,7 @@ class TestHarness { config: new ConfigReader({}), logger, processingDatabase, + knex: db, orchestrator, stitcher, createHash: () => createHash('sha1'), @@ -300,7 +301,16 @@ class TestHarness { return new TestHarness( catalog, - engine, + { + async start() { + await engine.start(); + await stitcher.start(); + }, + async stop() { + await engine.stop(); + await stitcher.stop(); + }, + }, refresh, provider, proxyProgressTracker, diff --git a/plugins/catalog-backend/src/tests/performance/stitchingPerformance.test.ts b/plugins/catalog-backend/src/tests/performance/stitchingPerformance.test.ts index e60c0a33d6..c1a869f9ad 100644 --- a/plugins/catalog-backend/src/tests/performance/stitchingPerformance.test.ts +++ b/plugins/catalog-backend/src/tests/performance/stitchingPerformance.test.ts @@ -181,6 +181,7 @@ describePerformanceTest('stitchingPerformance', () => { const backend = await startTestBackend({ features: [ import('@backstage/plugin-catalog-backend/alpha'), + staticDatabase(knex), createBackendModule({ moduleId: 'syntheticLoadEntities', pluginId: 'catalog', @@ -200,7 +201,6 @@ describePerformanceTest('stitchingPerformance', () => { }); }, }), - staticDatabase(knex), ], }); From 9e46f5ff49c0ca6bb98250e7484345fc168c12e6 Mon Sep 17 00:00:00 2001 From: zcason Date: Wed, 20 Sep 2023 15:16:00 -0500 Subject: [PATCH 024/110] new changeset for each plugin Signed-off-by: zcason --- .changeset/dull-dolls-explode.md | 5 +++++ .changeset/eighty-wasps-remain.md | 6 ------ .changeset/short-planets-suffer.md | 5 +++++ 3 files changed, 10 insertions(+), 6 deletions(-) create mode 100644 .changeset/dull-dolls-explode.md delete mode 100644 .changeset/eighty-wasps-remain.md create mode 100644 .changeset/short-planets-suffer.md diff --git a/.changeset/dull-dolls-explode.md b/.changeset/dull-dolls-explode.md new file mode 100644 index 0000000000..10088e0818 --- /dev/null +++ b/.changeset/dull-dolls-explode.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-playlist-backend': patch +--- + +Added support to the playlist plugin for the new backend diff --git a/.changeset/eighty-wasps-remain.md b/.changeset/eighty-wasps-remain.md deleted file mode 100644 index e6ecfde660..0000000000 --- a/.changeset/eighty-wasps-remain.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-playlist-backend': patch -'@backstage/plugin-graphql-backend': patch ---- - -Added support to graphql and playlist for new backend diff --git a/.changeset/short-planets-suffer.md b/.changeset/short-planets-suffer.md new file mode 100644 index 0000000000..9626a05e54 --- /dev/null +++ b/.changeset/short-planets-suffer.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-graphql-backend': patch +--- + +Added support to the graphql plugin for the new backend From 38fddab7d54e570ac15b3bcaedf07e38341e6868 Mon Sep 17 00:00:00 2001 From: zcason Date: Wed, 20 Sep 2023 15:17:32 -0500 Subject: [PATCH 025/110] readme update Signed-off-by: zcason --- plugins/graphql-backend/README.md | 7 ++++--- plugins/playlist-backend/README.md | 11 +++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/plugins/graphql-backend/README.md b/plugins/graphql-backend/README.md index 11453ec8bc..d1bd53b38d 100644 --- a/plugins/graphql-backend/README.md +++ b/plugins/graphql-backend/README.md @@ -29,14 +29,15 @@ This will launch the full example backend. ### New Backend System -The Grahpql backend plugin has support for the [new backend system](https://backstage.io/docs/backend-system/), here's how you can set that up: +The grahpql backend plugin has support for the [new backend system](https://backstage.io/docs/backend-system/), here's how you can set that up: In your `packages/backend/src/index.ts` make the following changes: ```diff -+ import { graphqlPlugin } from '@backstage/plugin-graphql-backend'; +import { createBackend } from '@backstage/backend-defaults'; const backend = createBackend(); -+ backend.add(graphqlPlugin()); + +backend.add(import('@backstage/plugin-graphql-backend')); // ... other feature additions backend.start(); diff --git a/plugins/playlist-backend/README.md b/plugins/playlist-backend/README.md index e336ec5b08..b5c9b8797b 100644 --- a/plugins/playlist-backend/README.md +++ b/plugins/playlist-backend/README.md @@ -93,13 +93,12 @@ The Playlist backend plugin has support for the [new backend system](https://bac In your `packages/backend/src/index.ts` make the following changes: ```diff - import { createBackend } from '@backstage/backend-defaults'; -+ import { playlistPlugin } from '@backstage/plugin-playlist-backend'; - const backend = createBackend(); +import { createBackend } from '@backstage/backend-defaults'; - // ... other feature additions +const backend = createBackend(); -+ backend.add(playlistPlugin()); +backend.add(import('@backstage/plugin-playlist-backend')); +// ... other feature additions - backend.start(); +backend.start(); ``` From 50ea05fb73ed91a89a833b2a39ef8ffc226b0cf1 Mon Sep 17 00:00:00 2001 From: Anton Ganhammar Date: Wed, 20 Sep 2023 22:25:21 +0200 Subject: [PATCH 026/110] feat: fix dev server Signed-off-by: Anton Ganhammar --- .../dev/__fixtures__/coverage-for-entity.json | 174 ++++++++++++++++++ .../coverage-history-for-entity.json | 84 +++++++++ .../__fixtures__/file-content-index-js.txt | 16 ++ .../dev/__fixtures__/file-content-math-js.txt | 29 +++ .../get-file-content-from-entity.ts | 64 +++++++ plugins/code-coverage/dev/index.tsx | 56 +++++- 6 files changed, 422 insertions(+), 1 deletion(-) create mode 100644 plugins/code-coverage/dev/__fixtures__/coverage-for-entity.json create mode 100644 plugins/code-coverage/dev/__fixtures__/coverage-history-for-entity.json create mode 100644 plugins/code-coverage/dev/__fixtures__/file-content-index-js.txt create mode 100644 plugins/code-coverage/dev/__fixtures__/file-content-math-js.txt create mode 100644 plugins/code-coverage/dev/__fixtures__/get-file-content-from-entity.ts diff --git a/plugins/code-coverage/dev/__fixtures__/coverage-for-entity.json b/plugins/code-coverage/dev/__fixtures__/coverage-for-entity.json new file mode 100644 index 0000000000..c2f4725818 --- /dev/null +++ b/plugins/code-coverage/dev/__fixtures__/coverage-for-entity.json @@ -0,0 +1,174 @@ +{ + "metadata": { + "vcs": { + "type": "github", + "location": "https://github.com/backstage/backstage/tree/main/" + }, + "generationTime": 1694413579498 + }, + "entity": { + "name": "backstage", + "namespace": "default", + "kind": "Component" + }, + "files": [ + { + "filename": "src/index.js", + "lineHits": { + "1": 1, + "2": 1, + "3": 1, + "4": 13, + "5": 13, + "6": 3, + "7": 13, + "8": 3, + "9": 13, + "10": 3, + "11": 13, + "12": 3, + "13": 13, + "14": 1, + "15": 13, + "16": 13 + }, + "branchHits": { + "3": { + "covered": 1, + "available": 1, + "missed": 0 + }, + "5": { + "covered": 1, + "available": 1, + "missed": 0 + }, + "7": { + "covered": 1, + "available": 1, + "missed": 0 + }, + "9": { + "covered": 1, + "available": 1, + "missed": 0 + }, + "11": { + "covered": 1, + "available": 1, + "missed": 0 + }, + "13": { + "covered": 1, + "available": 1, + "missed": 0 + } + } + }, + { + "filename": "src/math.js", + "lineHits": { + "1": 1, + "2": 3, + "3": 2, + "4": 2, + "5": 1, + "6": 1, + "7": 1, + "8": 1, + "9": 3, + "10": 2, + "11": 2, + "12": 1, + "13": 1, + "14": 1, + "15": 1, + "16": 3, + "17": 2, + "18": 2, + "19": 1, + "20": 1, + "21": 1, + "22": 1, + "23": 3, + "24": 2, + "25": 3, + "26": 0, + "27": 0, + "28": 1, + "29": 1 + }, + "branchHits": { + "2": { + "covered": 3, + "available": 3, + "missed": 0 + }, + "5": { + "covered": 1, + "available": 1, + "missed": 0 + }, + "8": { + "covered": 1, + "available": 1, + "missed": 0 + }, + "9": { + "covered": 2, + "available": 2, + "missed": 0 + }, + "12": { + "covered": 1, + "available": 1, + "missed": 0 + }, + "15": { + "covered": 1, + "available": 1, + "missed": 0 + }, + "16": { + "covered": 2, + "available": 2, + "missed": 0 + }, + "19": { + "covered": 1, + "available": 1, + "missed": 0 + }, + "22": { + "covered": 1, + "available": 1, + "missed": 0 + }, + "23": { + "covered": 2, + "available": 2, + "missed": 0 + }, + "25": { + "covered": 1, + "available": 2, + "missed": 1 + } + } + } + ], + "aggregate": { + "line": { + "available": 45, + "covered": 43, + "missed": 2, + "percentage": 95.56 + }, + "branch": { + "available": 23, + "covered": 22, + "missed": 1, + "percentage": 95.65 + } + } +} diff --git a/plugins/code-coverage/dev/__fixtures__/coverage-history-for-entity.json b/plugins/code-coverage/dev/__fixtures__/coverage-history-for-entity.json new file mode 100644 index 0000000000..26b96875e5 --- /dev/null +++ b/plugins/code-coverage/dev/__fixtures__/coverage-history-for-entity.json @@ -0,0 +1,84 @@ +{ + "entity": { + "name": "backstage", + "kind": "component", + "namespace": "default" + }, + "history": [ + { + "timestamp": 1694413579498, + "branch": { + "available": 23, + "covered": 22, + "missed": 1, + "percentage": 95.65 + }, + "line": { + "available": 45, + "covered": 43, + "missed": 2, + "percentage": 95.56 + } + }, + { + "timestamp": 1694178927072, + "branch": { + "available": 23, + "covered": 22, + "missed": 1, + "percentage": 95.65 + }, + "line": { + "available": 45, + "covered": 43, + "missed": 2, + "percentage": 95.56 + } + }, + { + "timestamp": 1694178830777, + "branch": { + "available": 19, + "covered": 18, + "missed": 1, + "percentage": 94.74 + }, + "line": { + "available": 45, + "covered": 43, + "missed": 2, + "percentage": 95.56 + } + }, + { + "timestamp": 1694178708402, + "branch": { + "available": 15, + "covered": 10, + "missed": 5, + "percentage": 66.67 + }, + "line": { + "available": 45, + "covered": 36, + "missed": 9, + "percentage": 80 + } + }, + { + "timestamp": 1694178270486, + "branch": { + "available": 10, + "covered": 5, + "missed": 5, + "percentage": 50 + }, + "line": { + "available": 45, + "covered": 26, + "missed": 19, + "percentage": 57.78 + } + } + ] +} diff --git a/plugins/code-coverage/dev/__fixtures__/file-content-index-js.txt b/plugins/code-coverage/dev/__fixtures__/file-content-index-js.txt new file mode 100644 index 0000000000..34df5226d5 --- /dev/null +++ b/plugins/code-coverage/dev/__fixtures__/file-content-index-js.txt @@ -0,0 +1,16 @@ +import { add, multiply, subtract, divide } from "./math"; + +export default (a, b, operator) => { + switch(operator) { + case '+': + return add(a, b); + case '-': + return subtract(a, b); + case '*': + return multiply(a, b); + case '/': + return divide(a, b); + default: + throw new Error('Invalid operator'); + } +}; diff --git a/plugins/code-coverage/dev/__fixtures__/file-content-math-js.txt b/plugins/code-coverage/dev/__fixtures__/file-content-math-js.txt new file mode 100644 index 0000000000..05f43438f5 --- /dev/null +++ b/plugins/code-coverage/dev/__fixtures__/file-content-math-js.txt @@ -0,0 +1,29 @@ +export function add(a, b) { + if (isNaN(a) || isNaN(b)) { + throw new Error('Invalid input'); + } + return a + b; +} + +export function subtract(a, b) { + if (isNaN(a) || isNaN(b)) { + throw new Error('Invalid input'); + } + return a - b; +} + +export function multiply(a, b) { + if (isNaN(a) || isNaN(b)) { + throw new Error('Invalid input'); + } + return a * b; +} + +export function divide(a, b) { + if (isNaN(a) || isNaN(b)) { + throw new Error('Invalid input'); + } else if (b === 0) { + throw new Error('Division by zero'); + } + return a / b; +} diff --git a/plugins/code-coverage/dev/__fixtures__/get-file-content-from-entity.ts b/plugins/code-coverage/dev/__fixtures__/get-file-content-from-entity.ts new file mode 100644 index 0000000000..9fea0997f7 --- /dev/null +++ b/plugins/code-coverage/dev/__fixtures__/get-file-content-from-entity.ts @@ -0,0 +1,64 @@ +/* + * 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. + */ +export default { + 'src/index.js': `import { add, multiply, subtract, divide } from \"./math\"; + +export default (a, b, operator) => { + switch(operator) { + case '+': + return add(a, b); + case '-': + return subtract(a, b); + case '*': + return multiply(a, b); + case '/': + return divide(a, b); + default: + throw new Error('Invalid operator'); + } +}; + `, + 'src/math.js': `export function add(a, b) { + if (isNaN(a) || isNaN(b)) { + throw new Error('Invalid input'); + } + return a + b; +} + +export function subtract(a, b) { + if (isNaN(a) || isNaN(b)) { + throw new Error('Invalid input'); + } + return a - b; +} + +export function multiply(a, b) { + if (isNaN(a) || isNaN(b)) { + throw new Error('Invalid input'); + } + return a * b; +} + +export function divide(a, b) { + if (isNaN(a) || isNaN(b)) { + throw new Error('Invalid input'); + } else if (b === 0) { + throw new Error('Division by zero'); + } + return a / b; +} + `, +}; diff --git a/plugins/code-coverage/dev/index.tsx b/plugins/code-coverage/dev/index.tsx index f364c2a0d1..e0c1ef7616 100644 --- a/plugins/code-coverage/dev/index.tsx +++ b/plugins/code-coverage/dev/index.tsx @@ -16,11 +16,65 @@ import React from 'react'; import { createDevApp } from '@backstage/dev-utils'; import { codeCoveragePlugin, EntityCodeCoverageContent } from '../src/plugin'; +import { CompoundEntityRef, Entity } from '@backstage/catalog-model'; +import { EntityProvider } from '@backstage/plugin-catalog-react'; +import { codeCoverageApiRef, CodeCoverageApi } from '../src/api'; +import coverageForEntity from './__fixtures__/coverage-for-entity.json'; +import coverageHistoryForEntity from './__fixtures__/coverage-history-for-entity.json'; +import fileContentFromEntity from './__fixtures__/get-file-content-from-entity'; + +const mockEntity: Entity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + name: 'backstage', + description: 'backstage.io', + annotations: { + 'backstage.io/code-coverage': 'enabled', + }, + }, + spec: { + lifecycle: 'production', + type: 'website', + owner: 'user:guest', + }, +}; + +const mockCodeCoverageApi: CodeCoverageApi = { + async getCoverageForEntity(_entity: CompoundEntityRef) { + return coverageForEntity as any; + }, + async getFileContentFromEntity(_entity: CompoundEntityRef, filePath: string) { + switch (filePath) { + case 'src/index.js': + return fileContentFromEntity['src/index.js']; + case 'src/math.js': + return fileContentFromEntity['src/math.js']; + default: + return ''; + } + }, + async getCoverageHistoryForEntity( + _entity: CompoundEntityRef, + _limit?: number, + ) { + return coverageHistoryForEntity; + }, +}; createDevApp() + .registerApi({ + api: codeCoverageApiRef, + deps: {}, + factory: () => mockCodeCoverageApi, + }) .registerPlugin(codeCoveragePlugin) .addPage({ - element: , + element: ( + + + + ), title: 'Root Page', }) .render(); From 2215e4c80162b3a9b010a05d387511e49a2af266 Mon Sep 17 00:00:00 2001 From: Anton Ganhammar Date: Wed, 20 Sep 2023 22:34:18 +0200 Subject: [PATCH 027/110] fix: current statistics Signed-off-by: Anton Ganhammar --- .../components/CoverageHistoryChart/CoverageHistoryChart.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/code-coverage/src/components/CoverageHistoryChart/CoverageHistoryChart.tsx b/plugins/code-coverage/src/components/CoverageHistoryChart/CoverageHistoryChart.tsx index 1e5341eb50..09f499fafd 100644 --- a/plugins/code-coverage/src/components/CoverageHistoryChart/CoverageHistoryChart.tsx +++ b/plugins/code-coverage/src/components/CoverageHistoryChart/CoverageHistoryChart.tsx @@ -113,8 +113,8 @@ export const CoverageHistoryChart = () => { ); } - const oldestCoverage = valueHistory.history[0]; - const [latestCoverage] = valueHistory.history.slice(-1); + const [oldestCoverage] = valueHistory.history.slice(-1); + const latestCoverage = valueHistory.history[0]; const getTrendForCoverage = (type: Coverage) => { if (!oldestCoverage[type].percentage) { From 3c0af9a07840e17b0951b6d13cc81007a906cba8 Mon Sep 17 00:00:00 2001 From: Anton Ganhammar Date: Wed, 20 Sep 2023 22:35:22 +0200 Subject: [PATCH 028/110] feat: update layout to improve contrasts and consistency with other plugins Signed-off-by: Anton Ganhammar --- .../src/components/FileExplorer/CodeRow.tsx | 4 + .../components/FileExplorer/FileExplorer.tsx | 172 +++++++++--------- .../components/FileExplorer/Highlighter.ts | 11 +- 3 files changed, 99 insertions(+), 88 deletions(-) diff --git a/plugins/code-coverage/src/components/FileExplorer/CodeRow.tsx b/plugins/code-coverage/src/components/FileExplorer/CodeRow.tsx index c7dee55f2b..20f0548f16 100644 --- a/plugins/code-coverage/src/components/FileExplorer/CodeRow.tsx +++ b/plugins/code-coverage/src/components/FileExplorer/CodeRow.tsx @@ -41,9 +41,11 @@ const useStyles = makeStyles(theme => ({ }, hitCountRoundedRectangle: { backgroundColor: `${theme.palette.success.main}`, + color: `${theme.palette.success.contrastText}`, }, notHitCountRoundedRectangle: { backgroundColor: `${theme.palette.error.main}`, + color: `${theme.palette.error.contrastText}`, }, codeLine: { paddingLeft: `${theme.spacing(1)}`, @@ -52,9 +54,11 @@ const useStyles = makeStyles(theme => ({ }, hitCodeLine: { backgroundColor: `${theme.palette.success.main}`, + color: `${theme.palette.success.contrastText}`, }, notHitCodeLine: { backgroundColor: `${theme.palette.error.main}`, + color: `${theme.palette.error.contrastText}`, }, })); diff --git a/plugins/code-coverage/src/components/FileExplorer/FileExplorer.tsx b/plugins/code-coverage/src/components/FileExplorer/FileExplorer.tsx index 3d41a1ff64..4017ba8264 100644 --- a/plugins/code-coverage/src/components/FileExplorer/FileExplorer.tsx +++ b/plugins/code-coverage/src/components/FileExplorer/FileExplorer.tsx @@ -15,15 +15,9 @@ */ import { useEntity } from '@backstage/plugin-catalog-react'; -import { - Box, - Card, - CardContent, - CardHeader, - Modal, - Tooltip, -} from '@material-ui/core'; -import DescriptionIcon from '@material-ui/icons/Description'; +import { Box, Modal, makeStyles } from '@material-ui/core'; +import FolderIcon from '@material-ui/icons/Folder'; +import FileOutlinedIcon from '@material-ui/icons/InsertDriveFileOutlined'; import { Alert } from '@material-ui/lab'; import React, { Fragment, useEffect, useState } from 'react'; import useAsync from 'react-use/lib/useAsync'; @@ -38,6 +32,19 @@ import { } from '@backstage/core-components'; import { useApi } from '@backstage/core-plugin-api'; +const useStyles = makeStyles(theme => ({ + container: { + marginTop: theme.spacing(2), + }, + icon: { + marginRight: theme.spacing(1), + }, + link: { + color: theme.palette.primary.main, + cursor: 'pointer', + }, +})); + type FileStructureObject = Record; type CoverageTableRow = { @@ -143,6 +150,7 @@ export const getObjectsAtPath = ( }; export const FileExplorer = () => { + const styles = useStyles(); const { entity } = useEntity(); const [curData, setCurData] = useState(); const [tableData, setTableData] = useState(); @@ -188,6 +196,7 @@ export const FileExplorer = () => { const moveUpIntoPath = (idx: number) => { const path = curPath.split('/').slice(0, idx + 1); + setCurFile(''); setCurPath(path.join('/')); setTableData(getObjectsAtPath(curData, path.slice(1))); }; @@ -197,43 +206,32 @@ export const FileExplorer = () => { title: 'Path', type: 'string', field: 'path', - render: (row: CoverageTableRow) => { - if (row.files?.length) { - return ( -
{ - setCurPath(`${curPath}/${row.path}`); - moveDownIntoPath(row.path); - }} - onClick={() => { - setCurPath(`${curPath}/${row.path}`); - moveDownIntoPath(row.path); - }} - > - {row.path} -
- ); - } - - return ( - - {row.path} - - { - setCurFile(`${curPath.slice(1)}/${row.path}`); - setModalOpen(true); - }} - /> - - - ); - }, + render: (row: CoverageTableRow) => ( + { + if (row.files?.length) { + setCurPath(`${curPath}/${row.path}`); + moveDownIntoPath(row.path); + } else { + setCurFile(`${curPath.slice(1)}/${row.path}`); + setModalOpen(true); + } + }} + > + {row.files?.length > 0 && ( + + )} + {row.files?.length === 0 && ( + + )} + {row.path} + + ), }, { title: 'Coverage', @@ -264,42 +262,50 @@ export const FileExplorer = () => { } return ( - - - - - {pathArray.map((pathElement, idx) => ( - -
moveUpIntoPath(idx)} - onClick={() => moveUpIntoPath(idx)} - > - {pathElement || 'root'} -
-
{'\u00A0/\u00A0'}
-
- ))} -
- No files found} - data={tableData || []} - columns={columns} - /> - event.stopPropagation()} - onClose={() => setModalOpen(false)} - style={{ overflow: 'scroll' }} - > - - - - + +
No files found} + data={tableData || []} + columns={columns} + title={ + <> + Explore Files + + {pathArray.map((pathElement, idx) => ( + +
moveUpIntoPath(idx)} + onClick={() => moveUpIntoPath(idx)} + > + {pathElement || 'root'} +
+ {idx !== lastPathElementIndex &&
{'\u00A0/\u00A0'}
} +
+ ))} +
+ + } + /> + event.stopPropagation()} + onClose={() => setModalOpen(false)} + style={{ overflow: 'scroll' }} + > + + + ); }; diff --git a/plugins/code-coverage/src/components/FileExplorer/Highlighter.ts b/plugins/code-coverage/src/components/FileExplorer/Highlighter.ts index d97d147da3..465e43f6e4 100644 --- a/plugins/code-coverage/src/components/FileExplorer/Highlighter.ts +++ b/plugins/code-coverage/src/components/FileExplorer/Highlighter.ts @@ -14,8 +14,8 @@ * limitations under the License. */ -import 'highlight.js/styles/atom-one-dark.css'; -import highlight from 'highlight.js'; +import 'highlight.js/styles/mono-blue.css'; +import { highlight } from 'highlight.js'; /* * Given a file extension, repo name, and array of code lines, return a Promise resolving @@ -30,7 +30,6 @@ import highlight from 'highlight.js'; */ export const highlightLines = (fileExtension: string, lines: Array) => { const formattedLines: Array = []; - let state: CompiledMode | Language | undefined; let fileformat = fileExtension; if (fileExtension === 'm') { fileformat = 'objectivec'; @@ -46,8 +45,10 @@ export const highlightLines = (fileExtension: string, lines: Array) => { } lines.forEach(line => { - const result = highlight.highlight(fileformat, line, true, state); - state = result.top; + const result = highlight(line, { + language: fileformat, + ignoreIllegals: true, + }); formattedLines.push(result.value); }); return formattedLines; From a468544fa9a868726d4d02e6282b5b92b973a8f4 Mon Sep 17 00:00:00 2001 From: Anton Ganhammar Date: Wed, 20 Sep 2023 22:37:53 +0200 Subject: [PATCH 029/110] chore: add changeset Signed-off-by: Anton Ganhammar --- .changeset/stupid-eagles-shave.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/stupid-eagles-shave.md diff --git a/.changeset/stupid-eagles-shave.md b/.changeset/stupid-eagles-shave.md new file mode 100644 index 0000000000..9bd88290ee --- /dev/null +++ b/.changeset/stupid-eagles-shave.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-code-coverage': patch +--- + +Updated layout to improve contrasts and consistency with other plugins From d3ecb8aa3daf0d6eaa2c4a0c89398e2edc401d96 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Thu, 21 Sep 2023 11:04:44 +0200 Subject: [PATCH 030/110] rename to subtitle Signed-off-by: Johan Haals --- plugins/tech-radar/src/alpha.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/plugins/tech-radar/src/alpha.tsx b/plugins/tech-radar/src/alpha.tsx index 29b170c957..6a2ec882ba 100644 --- a/plugins/tech-radar/src/alpha.tsx +++ b/plugins/tech-radar/src/alpha.tsx @@ -35,7 +35,7 @@ export const TechRadarPage = createPageExtension({ configSchema: createSchemaFromZod(z => z.object({ title: z.string().default('Tech Radar'), - subTitle: z + subtitle: z .string() .default('Pick the recommended technologies for your projects'), pageTitle: z.string().default('Company Radar'), @@ -45,9 +45,7 @@ export const TechRadarPage = createPageExtension({ }), ), loader: ({ config }) => - import('./components').then(m => ( - - )), + import('./components').then(m => ), }); const sampleTechRadarApi = createApiExtension({ From 9d03dfe5e319a47ce15bb8e952cf7b4736dbc6b3 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 22 Sep 2023 12:23:51 +0200 Subject: [PATCH 031/110] frontend-app-api: make app initialization async Signed-off-by: Patrik Oldsberg --- .changeset/polite-cooks-perform.md | 5 ++ packages/frontend-app-api/api-report.md | 3 +- .../frontend-app-api/src/wiring/createApp.tsx | 83 +++++++++++-------- .../src/wiring/createPlugin.test.ts | 24 +++--- 4 files changed, 70 insertions(+), 45 deletions(-) create mode 100644 .changeset/polite-cooks-perform.md diff --git a/.changeset/polite-cooks-perform.md b/.changeset/polite-cooks-perform.md new file mode 100644 index 0000000000..40766c84a3 --- /dev/null +++ b/.changeset/polite-cooks-perform.md @@ -0,0 +1,5 @@ +--- +'@backstage/frontend-app-api': minor +--- + +The `createApp` config option has been replaced by a new `configLoader` option. There is now also a `pluginLoader` option that can be used to dynamically load plugins into the app. diff --git a/packages/frontend-app-api/api-report.md b/packages/frontend-app-api/api-report.md index 12cf853f9d..2e77ef904b 100644 --- a/packages/frontend-app-api/api-report.md +++ b/packages/frontend-app-api/api-report.md @@ -12,7 +12,8 @@ import { JSX as JSX_2 } from 'react'; // @public (undocumented) export function createApp(options: { plugins: BackstagePlugin[]; - config?: ConfigApi; + configLoader?: () => Promise; + pluginLoader?: (ctx: { config: ConfigApi }) => Promise; }): { createRoot(): JSX_2.Element; }; diff --git a/packages/frontend-app-api/src/wiring/createApp.tsx b/packages/frontend-app-api/src/wiring/createApp.tsx index 462bfcdccc..f722d3594e 100644 --- a/packages/frontend-app-api/src/wiring/createApp.tsx +++ b/packages/frontend-app-api/src/wiring/createApp.tsx @@ -247,50 +247,67 @@ export function createInstances(options: { /** @public */ export function createApp(options: { plugins: BackstagePlugin[]; - config?: ConfigApi; + configLoader?: () => Promise; + pluginLoader?: (ctx: { config: ConfigApi }) => Promise; }): { createRoot(): JSX.Element; } { - const discoveredPlugins = getAvailablePlugins(); - const allPlugins = Array.from( - new Set([...discoveredPlugins, ...options.plugins]), - ); - const appConfig = - options?.config ?? - ConfigReader.fromConfigs(overrideBaseUrlConfigs(defaultConfigLoaderSync())); + async function appLoader() { + const config = + (await options?.configLoader?.()) ?? + ConfigReader.fromConfigs( + overrideBaseUrlConfigs(defaultConfigLoaderSync()), + ); - const { rootInstances } = createInstances({ - plugins: allPlugins, - config: appConfig, - }); + const discoveredPlugins = getAvailablePlugins(); + const loadedPlugins = (await options.pluginLoader?.({ config })) ?? []; + const allPlugins = Array.from( + new Set([...discoveredPlugins, ...options.plugins, ...loadedPlugins]), + ); - const routePaths = extractRouteInfoFromInstanceTree(rootInstances); + const { rootInstances } = createInstances({ + plugins: allPlugins, + config, + }); - const coreInstance = rootInstances.find(({ id }) => id === 'core'); - if (!coreInstance) { - throw Error('Unable to find core extension instance'); + const routePaths = extractRouteInfoFromInstanceTree(rootInstances); + + const coreInstance = rootInstances.find(({ id }) => id === 'core'); + if (!coreInstance) { + throw Error('Unable to find core extension instance'); + } + + const apiHolder = createApiHolder(coreInstance, config); + + const appContext = createLegacyAppContext(allPlugins); + + const rootElements = rootInstances + .map(e => e.getData(coreExtensionData.reactElement)) + .filter((x): x is JSX.Element => !!x); + + const App = () => ( + + + + + {/* TODO: set base path using the logic from AppRouter */} + {rootElements} + + + + + ); + + return { default: App }; } - const apiHolder = createApiHolder(coreInstance, appConfig); - - const appContext = createLegacyAppContext(allPlugins); - return { createRoot() { - const rootElements = rootInstances - .map(e => e.getData(coreExtensionData.reactElement)) - .filter((x): x is JSX.Element => !!x); + const LazyApp = React.lazy(appLoader); return ( - - - - - {/* TODO: set base path using the logic from AppRouter */} - {rootElements} - - - - + + + ); }, }; diff --git a/packages/frontend-plugin-api/src/wiring/createPlugin.test.ts b/packages/frontend-plugin-api/src/wiring/createPlugin.test.ts index 1d45c221af..b14838c17a 100644 --- a/packages/frontend-plugin-api/src/wiring/createPlugin.test.ts +++ b/packages/frontend-plugin-api/src/wiring/createPlugin.test.ts @@ -16,14 +16,14 @@ import React from 'react'; import { createApp } from '@backstage/frontend-app-api'; -import { render, screen } from '@testing-library/react'; +import { screen } from '@testing-library/react'; import { createSchemaFromZod } from '../schema/createSchemaFromZod'; import { createPlugin, BackstagePlugin } from './createPlugin'; import { JsonObject } from '@backstage/types'; import { createExtension } from './createExtension'; import { createExtensionDataRef } from './createExtensionDataRef'; import { coreExtensionData } from './coreExtensionData'; -import { MockConfigApi } from '@backstage/test-utils'; +import { MockConfigApi, renderWithEffects } from '@backstage/test-utils'; import { createExtensionInput } from './createExtensionInput'; const nameExtensionDataRef = createExtensionDataRef('name'); @@ -112,7 +112,7 @@ function createTestAppRoot({ }) { return createApp({ plugins: plugins, - config: new MockConfigApi(config), + configLoader: async () => new MockConfigApi(config), }).createRoot(); } @@ -123,24 +123,26 @@ describe('createPlugin', () => { expect(plugin).toBeDefined(); }); - it('should create a plugin with extension instances', () => { + it('should create a plugin with extension instances', async () => { const plugin = createPlugin({ id: 'empty', extensions: [TechRadarPage, CatalogPage, outputExtension], }); expect(plugin).toBeDefined(); - render( + await renderWithEffects( createTestAppRoot({ plugins: [plugin], config: { app: { extensions: [{ 'core.layout': false }] } }, }), ); - expect(screen.getByText('Names: TechRadar, Catalog')).toBeInTheDocument(); + await expect( + screen.findByText('Names: TechRadar, Catalog'), + ).resolves.toBeInTheDocument(); }); - it('should create a plugin with nested extension instances', () => { + it('should create a plugin with nested extension instances', async () => { const plugin = createPlugin({ id: 'empty', extensions: [ @@ -153,7 +155,7 @@ describe('createPlugin', () => { }); expect(plugin).toBeDefined(); - render( + await renderWithEffects( createTestAppRoot({ plugins: [plugin], config: { @@ -171,10 +173,10 @@ describe('createPlugin', () => { }), ); - expect( - screen.getByText( + await expect( + screen.findByText( 'Names: TechRadar, CatalogRenamed, TechDocs-TechDocsAddon', ), - ).toBeInTheDocument(); + ).resolves.toBeInTheDocument(); }); }); From deacb980537a4f74379865a6b72c61dc2d486a55 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 22 Sep 2023 13:46:12 +0200 Subject: [PATCH 032/110] frontend-app-api: key root elements Signed-off-by: Patrik Oldsberg --- packages/frontend-app-api/src/wiring/createApp.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/frontend-app-api/src/wiring/createApp.tsx b/packages/frontend-app-api/src/wiring/createApp.tsx index f722d3594e..80a3ecd1dc 100644 --- a/packages/frontend-app-api/src/wiring/createApp.tsx +++ b/packages/frontend-app-api/src/wiring/createApp.tsx @@ -282,7 +282,11 @@ export function createApp(options: { const appContext = createLegacyAppContext(allPlugins); const rootElements = rootInstances - .map(e => e.getData(coreExtensionData.reactElement)) + .map(e => ( + + {e.getData(coreExtensionData.reactElement)} + + )) .filter((x): x is JSX.Element => !!x); const App = () => ( From 348e8c1cdbb9ed17f523d6f33bdc4207115fead5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Thu, 21 Sep 2023 15:36:33 +0200 Subject: [PATCH 033/110] ensure stitching happens after eager deletion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/lovely-coins-occur.md | 5 + .../deleteWithEagerPruningOfChildren.test.ts | 53 ++- .../deleteWithEagerPruningOfChildren.ts | 365 +++++++++++------- 3 files changed, 271 insertions(+), 152 deletions(-) create mode 100644 .changeset/lovely-coins-occur.md diff --git a/.changeset/lovely-coins-occur.md b/.changeset/lovely-coins-occur.md new file mode 100644 index 0000000000..34a6774388 --- /dev/null +++ b/.changeset/lovely-coins-occur.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': patch +--- + +Fixes a bug where eagerly deleted entities did not properly trigger re-stitching of entities that they had relations to. diff --git a/plugins/catalog-backend/src/database/operations/provider/deleteWithEagerPruningOfChildren.test.ts b/plugins/catalog-backend/src/database/operations/provider/deleteWithEagerPruningOfChildren.test.ts index dcd87613de..830cc20480 100644 --- a/plugins/catalog-backend/src/database/operations/provider/deleteWithEagerPruningOfChildren.test.ts +++ b/plugins/catalog-backend/src/database/operations/provider/deleteWithEagerPruningOfChildren.test.ts @@ -18,7 +18,11 @@ import { TestDatabaseId, TestDatabases } from '@backstage/backend-test-utils'; import { Knex } from 'knex'; import * as uuid from 'uuid'; import { applyDatabaseMigrations } from '../../migrations'; -import { DbRefreshStateReferencesRow, DbRefreshStateRow } from '../../tables'; +import { + DbRefreshStateReferencesRow, + DbRefreshStateRow, + DbRelationsRow, +} from '../../tables'; import { deleteWithEagerPruningOfChildren } from './deleteWithEagerPruningOfChildren'; jest.setTimeout(60_000); @@ -43,6 +47,22 @@ describe('deleteWithEagerPruningOfChildren', () => { ); } + async function insertRelation( + knex: Knex, + ...relations: { from: string; to: string }[] + ) { + for (const rel of relations) { + await knex('relations').insert({ + originating_entity_id: await knex('refresh_state') + .select('entity_id') + .then(rows => rows[0].entity_id), // doesn't matter which one, this is consumed pre-deletion + source_entity_ref: rel.from, + target_entity_ref: rel.to, + type: 'fake', + }); + } + } + async function insertEntity(knex: Knex, ...entityRefs: string[]) { for (const ref of entityRefs) { await knex('refresh_state').insert({ @@ -64,6 +84,14 @@ describe('deleteWithEagerPruningOfChildren', () => { return rows.map(r => r.entity_ref); } + async function entitiesMarkedForStitching(knex: Knex) { + const rows = await knex('refresh_state') + .orderBy('entity_ref') + .select('entity_ref') + .where('result_hash', '=', 'force-stitching'); + return rows.map(r => r.entity_ref); + } + it.each(databases.eachSupportedId())( 'works for the simple path, %p', async databaseId => { @@ -78,7 +106,7 @@ describe('deleteWithEagerPruningOfChildren', () => { Scenario: P1 issues delete for E1 and E3 - Result: E1, E2, and E3 deleted; E4 and E5 remain + Result: E1, E2, and E3 deleted; E4 and E5 remain; E4 marked for stitching because it had a relation to a deleted entity */ const knex = await createDatabase(databaseId); await insertEntity(knex, 'E1', 'E2', 'E3', 'E4', 'E5'); @@ -90,12 +118,14 @@ describe('deleteWithEagerPruningOfChildren', () => { { source_key: 'P1', target_entity_ref: 'E4' }, { source_key: 'P2', target_entity_ref: 'E5' }, ); + await insertRelation(knex, { from: 'E4', to: 'E2' }); await deleteWithEagerPruningOfChildren({ knex, sourceKey: 'P1', entityRefs: ['E1', 'E3'], }); await expect(remainingEntities(knex)).resolves.toEqual(['E4', 'E5']); + await expect(entitiesMarkedForStitching(knex)).resolves.toEqual(['E4']); }, ); @@ -113,7 +143,7 @@ describe('deleteWithEagerPruningOfChildren', () => { Scenario: P1 issues delete for E1 - Result: E1 deleted; E2 remains + Result: E1 deleted; E2 remains; E2 marked for stitching because it had a relation to a deleted entity */ const knex = await createDatabase(databaseId); await insertEntity(knex, 'E1', 'E2'); @@ -123,12 +153,14 @@ describe('deleteWithEagerPruningOfChildren', () => { { source_key: 'P1', target_entity_ref: 'E1' }, { source_key: 'P1', target_entity_ref: 'E2' }, ); + await insertRelation(knex, { from: 'E2', to: 'E1' }); await deleteWithEagerPruningOfChildren({ knex, sourceKey: 'P1', entityRefs: ['E1'], }); await expect(remainingEntities(knex)).resolves.toEqual(['E2']); + await expect(entitiesMarkedForStitching(knex)).resolves.toEqual(['E2']); }, ); @@ -144,7 +176,7 @@ describe('deleteWithEagerPruningOfChildren', () => { Scenario: P1 issues delete for E1 - Result: E1 deleted; E2 and E3 remain + Result: E1 deleted; E2 and E3 remain; E2 marked for stitching because it had a relation to a deleted entity */ const knex = await createDatabase(databaseId); await insertEntity(knex, 'E1', 'E2', 'E3'); @@ -155,12 +187,18 @@ describe('deleteWithEagerPruningOfChildren', () => { { source_key: 'P2', target_entity_ref: 'E3' }, { source_entity_ref: 'E3', target_entity_ref: 'E2' }, ); + await insertRelation( + knex, + { from: 'E2', to: 'E1' }, + { from: 'E3', to: 'E2' }, + ); await deleteWithEagerPruningOfChildren({ knex, sourceKey: 'P1', entityRefs: ['E1'], }); await expect(remainingEntities(knex)).resolves.toEqual(['E2', 'E3']); + await expect(entitiesMarkedForStitching(knex)).resolves.toEqual(['E2']); }, ); @@ -193,6 +231,7 @@ describe('deleteWithEagerPruningOfChildren', () => { entityRefs: ['E1'], }); await expect(remainingEntities(knex)).resolves.toEqual(['E2', 'E3']); + await expect(entitiesMarkedForStitching(knex)).resolves.toEqual([]); }, ); @@ -208,7 +247,7 @@ describe('deleteWithEagerPruningOfChildren', () => { Scenario: P1 issues delete for E1, then for E3 - Result: Everything deleted, but in two steps + Result: Everything deleted, but in two steps; E4 marked for stitching in the first step because it had a relation to a deleted entity */ const knex = await createDatabase(databaseId); await insertEntity(knex, 'E1', 'E2', 'E3', 'E4', 'E5', 'E6'); @@ -224,6 +263,7 @@ describe('deleteWithEagerPruningOfChildren', () => { { source_entity_ref: 'E3', target_entity_ref: 'E5' }, { source_entity_ref: 'E5', target_entity_ref: 'E6' }, ); + await insertRelation(knex, { from: 'E4', to: 'E2' }); await deleteWithEagerPruningOfChildren({ knex, sourceKey: 'P1', @@ -235,12 +275,14 @@ describe('deleteWithEagerPruningOfChildren', () => { 'E5', 'E6', ]); + await expect(entitiesMarkedForStitching(knex)).resolves.toEqual(['E4']); await deleteWithEagerPruningOfChildren({ knex, sourceKey: 'P1', entityRefs: ['E3'], }); await expect(remainingEntities(knex)).resolves.toEqual([]); + await expect(entitiesMarkedForStitching(knex)).resolves.toEqual([]); }, ); @@ -277,6 +319,7 @@ describe('deleteWithEagerPruningOfChildren', () => { 'E2', 'E4', ]); + await expect(entitiesMarkedForStitching(knex)).resolves.toEqual([]); }, ); }); diff --git a/plugins/catalog-backend/src/database/operations/provider/deleteWithEagerPruningOfChildren.ts b/plugins/catalog-backend/src/database/operations/provider/deleteWithEagerPruningOfChildren.ts index 027860fcc6..70f7d08ed1 100644 --- a/plugins/catalog-backend/src/database/operations/provider/deleteWithEagerPruningOfChildren.ts +++ b/plugins/catalog-backend/src/database/operations/provider/deleteWithEagerPruningOfChildren.ts @@ -16,7 +16,11 @@ import { Knex } from 'knex'; import lodash from 'lodash'; -import { DbRefreshStateReferencesRow } from '../../tables'; +import { + DbFinalEntitiesRow, + DbRefreshStateReferencesRow, + DbRefreshStateRow, +} from '../../tables'; /** * Given a number of entity refs originally created by a given entity provider @@ -36,152 +40,24 @@ export async function deleteWithEagerPruningOfChildren(options: { // limits for the number of permitted bindings on a precompiled statement let removedCount = 0; for (const refs of lodash.chunk(entityRefs, 1000)) { - removedCount += await knex - .delete() - .from('refresh_state') - .whereIn('entity_ref', orphans => - orphans - // First find all nodes that can be reached downwards from the roots - // (deletion targets), including the roots themselves, by traversing - // down the refresh_state_references table. Note that this query - // starts with a condition that source_key = our source key, and - // target_entity_ref is one of the deletion targets. This has two - // effects: it won't match attempts at deleting something that didn't - // originate from us in the first place, and also won't match non-root - // entities (source_key would be null for those). - // - // KeyA - R1 - R2 Legend: - // \ ----------------------------------------- - // R3 Key* Source key - // / R* Entity ref - // KeyA - R4 - R5 lines Individual references; sources to - // / the left and targets to the right - // KeyB --- R6 - // - // The scenario is that KeyA wants to delete R1. - // - // The query starts with the KeyA-R1 reference, and then traverses - // down to also find R2 and R3. It uses union instead of union all, - // because it wants to find the set of unique descendants even if - // the tree has unexpected loops etc. - .withRecursive('descendants', ['entity_ref'], initial => - initial - .select('target_entity_ref') - .from('refresh_state_references') - .where('source_key', '=', sourceKey) - .whereIn('target_entity_ref', refs) - .union(recursive => - recursive - .select('refresh_state_references.target_entity_ref') - .from('descendants') - .join( - 'refresh_state_references', - 'descendants.entity_ref', - 'refresh_state_references.source_entity_ref', - ), - ), - ) - // Then for each descendant, traverse all the way back upwards through - // the refresh_state_references table to get an exhaustive list of all - // references that are part of keeping that particular descendant - // alive. - // - // Continuing the scenario from above, starting from R3, it goes - // upwards to find every pair along every relation line. - // - // Top branch: R2-R3, R1-R2, KeyA-R1 - // Middle branch: R5-R3, R4-R5, KeyA-R4 - // Bottom branch: R6-R5, KeyB-R6 - // - // Note that this all applied to the subject R3. The exact same thing - // will be done starting from each other descendant (R2 and R1). They - // only have one and two references to find, respectively. - // - // This query also uses union instead of union all, to get the set of - // distinct relations even if the tree has unexpected loops etc. - .withRecursive( - 'ancestors', - ['source_key', 'source_entity_ref', 'target_entity_ref', 'subject'], - initial => - initial - .select( - 'refresh_state_references.source_key', - 'refresh_state_references.source_entity_ref', - 'refresh_state_references.target_entity_ref', - 'descendants.entity_ref', - ) - .from('descendants') - .join( - 'refresh_state_references', - 'refresh_state_references.target_entity_ref', - 'descendants.entity_ref', - ) - .union(recursive => - recursive - .select( - 'refresh_state_references.source_key', - 'refresh_state_references.source_entity_ref', - 'refresh_state_references.target_entity_ref', - 'ancestors.subject', - ) - .from('ancestors') - .join( - 'refresh_state_references', - 'refresh_state_references.target_entity_ref', - 'ancestors.source_entity_ref', - ), - ), - ) - // Finally, from that list of ancestor relations per descendant, pick - // out the ones that are roots (have a source_key). Specifically, find - // ones that seem to be be either (1) from another source, or (2) - // aren't part of the deletion targets. Those are markers that tell us - // that the corresponding descendant should be kept alive and NOT - // subject to eager deletion, because there's "something else" (not - // targeted for deletion) that has references down through the tree to - // it. - // - // Continuing the scenario from above, for R3 we have - // - // KeyA-R1, KeyA-R4, KeyB-R6 - // - // This tells us that R3 should be kept alive for two reasons: it's - // referenced by a node that isn't being deleted (R4), and also by - // another source (KeyB). What about R1 and R2? They both have - // - // KeyA-R1 - // - // So those should be deleted, since they are definitely only being - // kept alive by something that's about to be deleted. - // - // Final shape of the tree: - // - // R3 - // / - // KeyA - R4 - R5 - // / - // KeyB --- R6 - .with('retained', ['entity_ref'], notPartOfDeletion => - notPartOfDeletion - .select('subject') - .from('ancestors') - .whereNotNull('ancestors.source_key') - .where(foreignKeyOrRef => - foreignKeyOrRef - .where('ancestors.source_key', '!=', sourceKey) - .orWhereNotIn('ancestors.target_entity_ref', refs), - ), - ) - // Return all descendants minus the retained ones - .select('descendants.entity_ref') - .from('descendants') - .leftOuterJoin( - 'retained', - 'retained.entity_ref', - 'descendants.entity_ref', - ) - .whereNull('retained.entity_ref'), - ); + const { orphanEntityRefs } = + await findDescendantsThatWouldHaveBeenOrphanedByDeletion({ + knex: options.knex, + refs, + sourceKey, + }); + + // Chunk again - these can be many more than the outer chunk size + for (const refsToDelete of lodash.chunk(orphanEntityRefs, 1000)) { + await markEntitiesAffectedByDeletionForStitching({ + knex: options.knex, + entityRefs: refsToDelete, + }); + await knex + .delete() + .from('refresh_state') + .whereIn('entity_ref', refsToDelete); + } // Delete the references that originate only from this entity provider. Note // that there may be more than one entity provider making a "claim" for a @@ -190,7 +66,202 @@ export async function deleteWithEagerPruningOfChildren(options: { .where('source_key', '=', sourceKey) .whereIn('target_entity_ref', refs) .delete(); + + removedCount += orphanEntityRefs.length; } return removedCount; } + +async function findDescendantsThatWouldHaveBeenOrphanedByDeletion(options: { + knex: Knex | Knex.Transaction; + refs: string[]; + sourceKey: string; +}): Promise<{ orphanEntityRefs: string[] }> { + const { knex, refs, sourceKey } = options; + + const orphans: string[] = + // First find all nodes that can be reached downwards from the roots + // (deletion targets), including the roots themselves, by traversing + // down the refresh_state_references table. Note that this query + // starts with a condition that source_key = our source key, and + // target_entity_ref is one of the deletion targets. This has two + // effects: it won't match attempts at deleting something that didn't + // originate from us in the first place, and also won't match non-root + // entities (source_key would be null for those). + // + // KeyA - R1 - R2 Legend: + // \ ----------------------------------------- + // R3 Key* Source key + // / R* Entity ref + // KeyA - R4 - R5 lines Individual references; sources to + // / the left and targets to the right + // KeyB --- R6 + // + // The scenario is that KeyA wants to delete R1. + // + // The query starts with the KeyA-R1 reference, and then traverses + // down to also find R2 and R3. It uses union instead of union all, + // because it wants to find the set of unique descendants even if + // the tree has unexpected loops etc. + await knex + .withRecursive('descendants', ['entity_ref'], initial => + initial + .select('target_entity_ref') + .from('refresh_state_references') + .where('source_key', '=', sourceKey) + .whereIn('target_entity_ref', refs) + .union(recursive => + recursive + .select('refresh_state_references.target_entity_ref') + .from('descendants') + .join( + 'refresh_state_references', + 'descendants.entity_ref', + 'refresh_state_references.source_entity_ref', + ), + ), + ) + // Then for each descendant, traverse all the way back upwards through + // the refresh_state_references table to get an exhaustive list of all + // references that are part of keeping that particular descendant + // alive. + // + // Continuing the scenario from above, starting from R3, it goes + // upwards to find every pair along every relation line. + // + // Top branch: R2-R3, R1-R2, KeyA-R1 + // Middle branch: R5-R3, R4-R5, KeyA-R4 + // Bottom branch: R6-R5, KeyB-R6 + // + // Note that this all applied to the subject R3. The exact same thing + // will be done starting from each other descendant (R2 and R1). They + // only have one and two references to find, respectively. + // + // This query also uses union instead of union all, to get the set of + // distinct relations even if the tree has unexpected loops etc. + .withRecursive( + 'ancestors', + ['source_key', 'source_entity_ref', 'target_entity_ref', 'subject'], + initial => + initial + .select( + 'refresh_state_references.source_key', + 'refresh_state_references.source_entity_ref', + 'refresh_state_references.target_entity_ref', + 'descendants.entity_ref', + ) + .from('descendants') + .join( + 'refresh_state_references', + 'refresh_state_references.target_entity_ref', + 'descendants.entity_ref', + ) + .union(recursive => + recursive + .select( + 'refresh_state_references.source_key', + 'refresh_state_references.source_entity_ref', + 'refresh_state_references.target_entity_ref', + 'ancestors.subject', + ) + .from('ancestors') + .join( + 'refresh_state_references', + 'refresh_state_references.target_entity_ref', + 'ancestors.source_entity_ref', + ), + ), + ) + // Finally, from that list of ancestor relations per descendant, pick + // out the ones that are roots (have a source_key). Specifically, find + // ones that seem to be be either (1) from another source, or (2) + // aren't part of the deletion targets. Those are markers that tell us + // that the corresponding descendant should be kept alive and NOT + // subject to eager deletion, because there's "something else" (not + // targeted for deletion) that has references down through the tree to + // it. + // + // Continuing the scenario from above, for R3 we have + // + // KeyA-R1, KeyA-R4, KeyB-R6 + // + // This tells us that R3 should be kept alive for two reasons: it's + // referenced by a node that isn't being deleted (R4), and also by + // another source (KeyB). What about R1 and R2? They both have + // + // KeyA-R1 + // + // So those should be deleted, since they are definitely only being + // kept alive by something that's about to be deleted. + // + // Final shape of the tree: + // + // R3 + // / + // KeyA - R4 - R5 + // / + // KeyB --- R6 + .with('retained', ['entity_ref'], notPartOfDeletion => + notPartOfDeletion + .select('subject') + .from('ancestors') + .whereNotNull('ancestors.source_key') + .where(foreignKeyOrRef => + foreignKeyOrRef + .where('ancestors.source_key', '!=', sourceKey) + .orWhereNotIn('ancestors.target_entity_ref', refs), + ), + ) + // Return all descendants minus the retained ones + .select('descendants.entity_ref AS entity_ref') + .from('descendants') + .leftOuterJoin( + 'retained', + 'retained.entity_ref', + 'descendants.entity_ref', + ) + .whereNull('retained.entity_ref') + .then(rows => rows.map(row => row.entity_ref)); + + return { orphanEntityRefs: orphans }; +} + +async function markEntitiesAffectedByDeletionForStitching(options: { + knex: Knex | Knex.Transaction; + entityRefs: string[]; +}) { + const { knex, entityRefs } = options; + + // We want to re-stitch anything that has a relation pointing to the + // soon-to-be-deleted entity. In many circumstances we also re-stitch children + // in the refresh_state_references graph because their orphan state might + // change, but not here - this code by its very definition is meant to not + // leave any orphans behind, so we can simplify away that. + const affectedIds = await knex + .select('refresh_state.entity_id AS entity_id') + .from('relations') + .join( + 'refresh_state', + 'relations.source_entity_ref', + 'refresh_state.entity_ref', + ) + .whereIn('relations.target_entity_ref', entityRefs) + .then(rows => rows.map(row => row.entity_id)); + + for (const ids of lodash.chunk(affectedIds, 1000)) { + await knex + .table('final_entities') + .update({ + hash: 'force-stitching', + }) + .whereIn('entity_id', ids); + await knex + .table('refresh_state') + .update({ + result_hash: 'force-stitching', + next_update_at: knex.fn.now(), + }) + .whereIn('entity_id', ids); + } +} From e232feec217d7a165db40de5141e844e05698268 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 23 Sep 2023 17:23:15 +0200 Subject: [PATCH 034/110] remove catalog-customized example Signed-off-by: Patrik Oldsberg --- packages/app-next/package.json | 2 +- packages/app/package.json | 2 +- packages/app/src/App.tsx | 2 +- .../components/catalog/EntityPage.test.tsx | 2 +- .../app/src/components/catalog/EntityPage.tsx | 2 +- .../app/src/components/search/SearchModal.tsx | 2 +- .../app/src/components/search/SearchPage.tsx | 2 +- plugins/catalog-customized/.eslintrc.js | 1 - plugins/catalog-customized/CHANGELOG.md | 457 ------------------ plugins/catalog-customized/README.md | 57 --- plugins/catalog-customized/api-report.md | 9 - plugins/catalog-customized/catalog-info.yaml | 12 - plugins/catalog-customized/package.json | 51 -- plugins/catalog-customized/src/index.ts | 18 - plugins/catalog-customized/src/plugin.ts | 22 - yarn.lock | 18 +- 16 files changed, 9 insertions(+), 650 deletions(-) delete mode 100644 plugins/catalog-customized/.eslintrc.js delete mode 100644 plugins/catalog-customized/CHANGELOG.md delete mode 100644 plugins/catalog-customized/README.md delete mode 100644 plugins/catalog-customized/api-report.md delete mode 100644 plugins/catalog-customized/catalog-info.yaml delete mode 100644 plugins/catalog-customized/package.json delete mode 100644 plugins/catalog-customized/src/index.ts delete mode 100644 plugins/catalog-customized/src/plugin.ts diff --git a/packages/app-next/package.json b/packages/app-next/package.json index e374f31dd9..07cae1498a 100644 --- a/packages/app-next/package.json +++ b/packages/app-next/package.json @@ -24,6 +24,7 @@ "@backstage/plugin-azure-devops": "workspace:^", "@backstage/plugin-azure-sites": "workspace:^", "@backstage/plugin-badges": "workspace:^", + "@backstage/plugin-catalog": "workspace:^", "@backstage/plugin-catalog-common": "workspace:^", "@backstage/plugin-catalog-graph": "workspace:^", "@backstage/plugin-catalog-import": "workspace:^", @@ -76,7 +77,6 @@ "@backstage/plugin-todo": "workspace:^", "@backstage/plugin-user-settings": "workspace:^", "@backstage/theme": "workspace:^", - "@internal/plugin-catalog-customized": "workspace:^", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.61", diff --git a/packages/app/package.json b/packages/app/package.json index 290c4211ff..f41145cb28 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -29,6 +29,7 @@ "@backstage/plugin-azure-devops": "workspace:^", "@backstage/plugin-azure-sites": "workspace:^", "@backstage/plugin-badges": "workspace:^", + "@backstage/plugin-catalog": "workspace:^", "@backstage/plugin-catalog-common": "workspace:^", "@backstage/plugin-catalog-graph": "workspace:^", "@backstage/plugin-catalog-import": "workspace:^", @@ -82,7 +83,6 @@ "@backstage/plugin-todo": "workspace:^", "@backstage/plugin-user-settings": "workspace:^", "@backstage/theme": "workspace:^", - "@internal/plugin-catalog-customized": "workspace:^", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.61", diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx index 6371182221..a0a6419328 100644 --- a/packages/app/src/App.tsx +++ b/packages/app/src/App.tsx @@ -46,7 +46,7 @@ import { CatalogEntityPage, CatalogIndexPage, catalogPlugin, -} from '@internal/plugin-catalog-customized'; +} from '@backstage/plugin-catalog'; import { CatalogGraphPage } from '@backstage/plugin-catalog-graph'; import { diff --git a/packages/app/src/components/catalog/EntityPage.test.tsx b/packages/app/src/components/catalog/EntityPage.test.tsx index f9d23247c6..68ce5fb497 100644 --- a/packages/app/src/components/catalog/EntityPage.test.tsx +++ b/packages/app/src/components/catalog/EntityPage.test.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import { EntityLayout } from '@internal/plugin-catalog-customized'; +import { EntityLayout } from '@backstage/plugin-catalog'; import { EntityProvider, starredEntitiesApiRef, diff --git a/packages/app/src/components/catalog/EntityPage.tsx b/packages/app/src/components/catalog/EntityPage.tsx index 25630253d4..ae78d0b771 100644 --- a/packages/app/src/components/catalog/EntityPage.tsx +++ b/packages/app/src/components/catalog/EntityPage.tsx @@ -68,7 +68,7 @@ import { hasLabels, hasRelationWarnings, EntityRelationWarning, -} from '@internal/plugin-catalog-customized'; +} from '@backstage/plugin-catalog'; import { Direction, EntityCatalogGraphCard, diff --git a/packages/app/src/components/search/SearchModal.tsx b/packages/app/src/components/search/SearchModal.tsx index 6b701d394d..23aec53a58 100644 --- a/packages/app/src/components/search/SearchModal.tsx +++ b/packages/app/src/components/search/SearchModal.tsx @@ -29,7 +29,7 @@ import { useSearch, } from '@backstage/plugin-search-react'; import { TechDocsSearchResultListItem } from '@backstage/plugin-techdocs'; -import { CatalogSearchResultListItem } from '@internal/plugin-catalog-customized'; +import { CatalogSearchResultListItem } from '@backstage/plugin-catalog'; import { Box, DialogActions, diff --git a/packages/app/src/components/search/SearchPage.tsx b/packages/app/src/components/search/SearchPage.tsx index 2e577e6589..a9f54cdb49 100644 --- a/packages/app/src/components/search/SearchPage.tsx +++ b/packages/app/src/components/search/SearchPage.tsx @@ -23,7 +23,7 @@ import { useSidebarPinState, } from '@backstage/core-components'; import { useApi } from '@backstage/core-plugin-api'; -import { CatalogSearchResultListItem } from '@internal/plugin-catalog-customized'; +import { CatalogSearchResultListItem } from '@backstage/plugin-catalog'; import { catalogApiRef, CATALOG_FILTER_EXISTS, diff --git a/plugins/catalog-customized/.eslintrc.js b/plugins/catalog-customized/.eslintrc.js deleted file mode 100644 index e2a53a6ad2..0000000000 --- a/plugins/catalog-customized/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/catalog-customized/CHANGELOG.md b/plugins/catalog-customized/CHANGELOG.md deleted file mode 100644 index ac858f652d..0000000000 --- a/plugins/catalog-customized/CHANGELOG.md +++ /dev/null @@ -1,457 +0,0 @@ -# @internal/plugin-catalog-customized - -## 0.0.14 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog@1.13.0 - - @backstage/plugin-catalog-react@1.8.4 - -## 0.0.14-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog@1.13.0-next.3 - - @backstage/plugin-catalog-react@1.8.4-next.3 - -## 0.0.14-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog@1.13.0-next.2 - - @backstage/plugin-catalog-react@1.8.4-next.2 - -## 0.0.14-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.4-next.1 - - @backstage/plugin-catalog@1.12.5-next.1 - -## 0.0.14-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog@1.12.4-next.0 - - @backstage/plugin-catalog-react@1.8.3-next.0 - -## 0.0.13 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog@1.12.1 - - @backstage/plugin-catalog-react@1.8.1 - -## 0.0.13-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.1-next.1 - - @backstage/plugin-catalog@1.12.1-next.2 - -## 0.0.13-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog@1.12.1-next.1 - - @backstage/plugin-catalog-react@1.8.1-next.0 - -## 0.0.13-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog@1.12.1-next.0 - - @backstage/plugin-catalog-react@1.8.1-next.0 - -## 0.0.12 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.0 - - @backstage/plugin-catalog@1.12.0 - -## 0.0.12-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.0-next.2 - - @backstage/plugin-catalog@1.12.0-next.2 - -## 0.0.12-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog@1.11.3-next.1 - - @backstage/plugin-catalog-react@1.7.1-next.1 - -## 0.0.12-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog@1.11.3-next.0 - - @backstage/plugin-catalog-react@1.7.1-next.0 - -## 0.0.11 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog@1.11.2 - - @backstage/plugin-catalog-react@1.7.0 - -## 0.0.11-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog@1.11.2-next.3 - - @backstage/plugin-catalog-react@1.7.0-next.3 - -## 0.0.11-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.7.0-next.2 - - @backstage/plugin-catalog@1.11.1-next.2 - -## 0.0.11-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog@1.11.1-next.1 - - @backstage/plugin-catalog-react@1.7.0-next.1 - -## 0.0.11-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.7.0-next.0 - - @backstage/plugin-catalog@1.11.1-next.0 - -## 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 - -- Updated dependencies - - @backstage/plugin-catalog@1.11.0-next.1 - - @backstage/plugin-catalog-react@1.6.0-next.1 - -## 0.0.10-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.6.0-next.0 - - @backstage/plugin-catalog@1.11.0-next.0 - -## 0.0.9 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.5.0 - - @backstage/plugin-catalog@1.10.0 - -## 0.0.9-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.5.0-next.3 - - @backstage/plugin-catalog@1.10.0-next.3 - -## 0.0.9-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.4.1-next.2 - - @backstage/plugin-catalog@1.10.0-next.2 - -## 0.0.9-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.4.1-next.1 - - @backstage/plugin-catalog@1.10.0-next.1 - -## 0.0.9-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog@1.10.0-next.0 - - @backstage/plugin-catalog-react@1.4.1-next.0 - -## 0.0.8 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog@1.9.0 - - @backstage/plugin-catalog-react@1.4.0 - -## 0.0.8-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.4.0-next.2 - - @backstage/plugin-catalog@1.9.0-next.2 - -## 0.0.8-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog@1.9.0-next.1 - - @backstage/plugin-catalog-react@1.4.0-next.1 - -## 0.0.8-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.4.0-next.0 - - @backstage/plugin-catalog@1.9.0-next.0 - -## 0.0.7 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog@1.8.0 - - @backstage/plugin-catalog-react@1.3.0 - -## 0.0.7-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog@1.8.0-next.2 - - @backstage/plugin-catalog-react@1.3.0-next.2 - -## 0.0.7-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog@1.8.0-next.1 - - @backstage/plugin-catalog-react@1.3.0-next.1 - -## 0.0.7-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.3.0-next.0 - - @backstage/plugin-catalog@1.7.3-next.0 - -## 0.0.6 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.4 - - @backstage/plugin-catalog@1.7.2 - -## 0.0.6-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.4-next.2 - - @backstage/plugin-catalog@1.7.2-next.2 - -## 0.0.6-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog@1.7.2-next.1 - - @backstage/plugin-catalog-react@1.2.4-next.1 - -## 0.0.6-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.4-next.0 - - @backstage/plugin-catalog@1.7.2-next.0 - -## 0.0.6 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog@1.7.1 - - @backstage/plugin-catalog-react@1.2.3 - -## 0.0.5 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog@1.7.0 - - @backstage/plugin-catalog-react@1.2.2 - -## 0.0.5-next.4 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog@1.7.0-next.4 - - @backstage/plugin-catalog-react@1.2.2-next.4 - -## 0.0.5-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog@1.7.0-next.3 - - @backstage/plugin-catalog-react@1.2.2-next.3 - -## 0.0.5-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog@1.7.0-next.2 - - @backstage/plugin-catalog-react@1.2.2-next.2 - -## 0.0.5-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog@1.6.2-next.1 - - @backstage/plugin-catalog-react@1.2.2-next.1 - -## 0.0.5-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.2-next.0 - - @backstage/plugin-catalog@1.6.2-next.0 - -## 0.0.4 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.1 - - @backstage/plugin-catalog@1.6.1 - -## 0.0.4-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog@1.6.1-next.1 - - @backstage/plugin-catalog-react@1.2.1-next.1 - -## 0.0.4-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.1-next.0 - - @backstage/plugin-catalog@1.6.1-next.0 - -## 0.0.3 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.0 - - @backstage/plugin-catalog@1.6.0 - -## 0.0.3-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog@1.6.0-next.2 - - @backstage/plugin-catalog-react@1.2.0-next.2 - -## 0.0.3-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.0-next.1 - - @backstage/plugin-catalog@1.6.0-next.1 - -## 0.0.3-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog@1.5.2-next.0 - - @backstage/plugin-catalog-react@1.1.5-next.0 - -## 0.0.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.4 - - @backstage/plugin-catalog@1.5.1 - -## 0.0.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.4-next.0 - - @backstage/plugin-catalog@1.5.1-next.0 - -## 0.0.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog@1.5.0 - - @backstage/plugin-catalog-react@1.1.3 - -## 0.0.1-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog@1.5.0-next.0 - - @backstage/plugin-catalog-react@1.1.3-next.0 diff --git a/plugins/catalog-customized/README.md b/plugins/catalog-customized/README.md deleted file mode 100644 index b7323d7430..0000000000 --- a/plugins/catalog-customized/README.md +++ /dev/null @@ -1,57 +0,0 @@ -# Backstage Catalog Frontend - -This is the React frontend to customize Backstage [software -catalog](http://backstage.io/docs/features/software-catalog/). -This package supplies the example how it can be achieved. - -## Installation - -This `@internal/plugin-catalog-customized` package comes installed by default in example application of -Backstage application. - -To check if you already have the package, look under -`packages/app/package.json`, in the `dependencies` block, for -`@internal/plugin-catalog-customized`. The instructions below walk through restoring the -plugin, if you previously removed it. - -### Install the package - -```bash -# From your Backstage root directory -yarn add --cwd packages/app @internal/plugin-catalog-customized -``` - -### Add the plugin to your `packages/app` - -Add the import to a file where is your plugin catalog is defined: - -```diff -// packages/app/src/App.tsx - -import from '@internal/plugin-catalog-customized'; - -... - -import { - CatalogIndexPage, - CatalogEntityPage, -} from '@backstage/plugin-catalog'; - -... -``` - -## Development - -This frontend plugin can be started in a standalone mode from directly in this -package with `yarn start`. However, it will have limited functionality and that -process is most convenient when developing the catalog frontend plugin itself. - -To evaluate the catalog and have a greater amount of functionality available, -run the entire Backstage example application from the root folder: - -```bash -yarn dev -``` - -This will launch both frontend and backend in the same window, populated with -some example entities. diff --git a/plugins/catalog-customized/api-report.md b/plugins/catalog-customized/api-report.md deleted file mode 100644 index 5cf6eefde1..0000000000 --- a/plugins/catalog-customized/api-report.md +++ /dev/null @@ -1,9 +0,0 @@ -## API Report File for "@internal/plugin-catalog-customized" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -export * from '@backstage/plugin-catalog'; - -// (No @packageDocumentation comment for this package) -``` diff --git a/plugins/catalog-customized/catalog-info.yaml b/plugins/catalog-customized/catalog-info.yaml deleted file mode 100644 index 1a6d0e0a00..0000000000 --- a/plugins/catalog-customized/catalog-info.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: internal-plugin-catalog-customized - title: '@internal/plugin-catalog-customized' - description: >- - The internal Backstage Customizable plugin for browsing the Backstage - catalog -spec: - lifecycle: experimental - type: backstage-frontend-plugin - owner: catalog-maintainers diff --git a/plugins/catalog-customized/package.json b/plugins/catalog-customized/package.json deleted file mode 100644 index 4c33911549..0000000000 --- a/plugins/catalog-customized/package.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "@internal/plugin-catalog-customized", - "description": "The internal Backstage Customizable plugin for browsing the Backstage catalog", - "version": "0.0.14", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", - "private": true, - "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/catalog-customized" - }, - "keywords": [ - "backstage" - ], - "sideEffects": false, - "scripts": { - "build": "backstage-cli package build", - "start": "backstage-cli package start", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", - "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" - }, - "dependencies": { - "@backstage/plugin-catalog": "workspace:^", - "@backstage/plugin-catalog-react": "workspace:^" - }, - "devDependencies": { - "@types/react": "^16.13.1 || ^17.0.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" - }, - "files": [ - "dist" - ] -} diff --git a/plugins/catalog-customized/src/index.ts b/plugins/catalog-customized/src/index.ts deleted file mode 100644 index cc8aefeaa6..0000000000 --- a/plugins/catalog-customized/src/index.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2020 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 './plugin'; - -export * from '@backstage/plugin-catalog'; diff --git a/plugins/catalog-customized/src/plugin.ts b/plugins/catalog-customized/src/plugin.ts deleted file mode 100644 index ce729d5226..0000000000 --- a/plugins/catalog-customized/src/plugin.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2020 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 { catalogPlugin } from '@backstage/plugin-catalog'; - -// id: 'catalog-customized' -catalogPlugin.__experimentalReconfigure({ - createButtonTitle: 'New', -}); diff --git a/yarn.lock b/yarn.lock index 9cb61d15f6..49d3b216a3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12015,20 +12015,6 @@ __metadata: languageName: node linkType: hard -"@internal/plugin-catalog-customized@workspace:^, @internal/plugin-catalog-customized@workspace:plugins/catalog-customized": - version: 0.0.0-use.local - resolution: "@internal/plugin-catalog-customized@workspace:plugins/catalog-customized" - dependencies: - "@backstage/plugin-catalog": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@types/react": ^16.13.1 || ^17.0.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 - languageName: unknown - linkType: soft - "@internal/plugin-todo-list-backend@workspace:plugins/example-todo-list-backend": version: 0.0.0-use.local resolution: "@internal/plugin-todo-list-backend@workspace:plugins/example-todo-list-backend" @@ -25355,6 +25341,7 @@ __metadata: "@backstage/plugin-azure-devops": "workspace:^" "@backstage/plugin-azure-sites": "workspace:^" "@backstage/plugin-badges": "workspace:^" + "@backstage/plugin-catalog": "workspace:^" "@backstage/plugin-catalog-common": "workspace:^" "@backstage/plugin-catalog-graph": "workspace:^" "@backstage/plugin-catalog-import": "workspace:^" @@ -25408,7 +25395,6 @@ __metadata: "@backstage/plugin-user-settings": "workspace:^" "@backstage/test-utils": "workspace:^" "@backstage/theme": "workspace:^" - "@internal/plugin-catalog-customized": "workspace:^" "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 @@ -25470,6 +25456,7 @@ __metadata: "@backstage/plugin-azure-devops": "workspace:^" "@backstage/plugin-azure-sites": "workspace:^" "@backstage/plugin-badges": "workspace:^" + "@backstage/plugin-catalog": "workspace:^" "@backstage/plugin-catalog-common": "workspace:^" "@backstage/plugin-catalog-graph": "workspace:^" "@backstage/plugin-catalog-import": "workspace:^" @@ -25524,7 +25511,6 @@ __metadata: "@backstage/plugin-user-settings": "workspace:^" "@backstage/test-utils": "workspace:^" "@backstage/theme": "workspace:^" - "@internal/plugin-catalog-customized": "workspace:^" "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 From 28f1ab2e1a885aaa541121ad57b0b279f78f95f7 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 23 Sep 2023 17:37:56 +0200 Subject: [PATCH 035/110] catalog: replace configure with i18n Signed-off-by: Patrik Oldsberg --- .changeset/gentle-elephants-fold.md | 20 ++++++++++++++++ plugins/catalog/alpha-api-report.md | 18 +++++++++++++++ plugins/catalog/api-report.md | 3 +-- plugins/catalog/package.json | 19 ++++++++++++--- plugins/catalog/src/alpha.ts | 17 ++++++++++++++ .../CatalogPage/DefaultCatalogPage.test.tsx | 3 +-- .../CatalogPage/DefaultCatalogPage.tsx | 10 ++++---- plugins/catalog/src/plugin.ts | 9 -------- .../src/{options.ts => translation.ts} | 23 ++++++++----------- 9 files changed, 88 insertions(+), 34 deletions(-) create mode 100644 .changeset/gentle-elephants-fold.md create mode 100644 plugins/catalog/alpha-api-report.md create mode 100644 plugins/catalog/src/alpha.ts rename plugins/catalog/src/{options.ts => translation.ts} (61%) diff --git a/.changeset/gentle-elephants-fold.md b/.changeset/gentle-elephants-fold.md new file mode 100644 index 0000000000..480ee41e7a --- /dev/null +++ b/.changeset/gentle-elephants-fold.md @@ -0,0 +1,20 @@ +--- +'@backstage/plugin-catalog': minor +--- + +The catalog plugin no longer implements the experimental reconfiguration API. The create button title can now instead be configured using the new experimental internationalization API, via the `catalogTranslationRef` exported at `/alpha`. For example: + +```ts +import { catalogTranslationRef } from '@backstage/plugin-catalog/alpha'; + +const app = createApp({ + __experimentalTranslations: { + resources: [ + createTranslationMessages({ + ref: catalogTranslationRef, + catalog_page_create_button_title: 'Create Software', + }), + ], + }, +}); +``` diff --git a/plugins/catalog/alpha-api-report.md b/plugins/catalog/alpha-api-report.md new file mode 100644 index 0000000000..27de408f86 --- /dev/null +++ b/plugins/catalog/alpha-api-report.md @@ -0,0 +1,18 @@ +## API Report File for "@backstage/plugin-catalog" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { TranslationRef } from '@backstage/core-plugin-api/alpha'; + +// @alpha (undocumented) +export const catalogTranslationRef: TranslationRef< + 'catalog', + { + readonly catalog_page_title: '{{orgName}} Catalog'; + readonly catalog_page_create_button_title: 'Create'; + } +>; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/catalog/api-report.md b/plugins/catalog/api-report.md index c8956dcbe8..8173c395ba 100644 --- a/plugins/catalog/api-report.md +++ b/plugins/catalog/api-report.md @@ -117,8 +117,7 @@ export const catalogPlugin: BackstagePlugin< }, true >; - }, - CatalogInputPluginOptions + } >; // @public (undocumented) diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json index 10a9eaf35e..dc03fb7b86 100644 --- a/plugins/catalog/package.json +++ b/plugins/catalog/package.json @@ -6,9 +6,22 @@ "types": "src/index.ts", "license": "Apache-2.0", "publishConfig": { - "access": "public", - "main": "dist/index.esm.js", - "types": "dist/index.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "frontend-plugin" diff --git a/plugins/catalog/src/alpha.ts b/plugins/catalog/src/alpha.ts new file mode 100644 index 0000000000..3509c1fb7f --- /dev/null +++ b/plugins/catalog/src/alpha.ts @@ -0,0 +1,17 @@ +/* + * 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. + */ + +export * from './translation'; diff --git a/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.test.tsx b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.test.tsx index f31d3baf39..b7d3ca3ed8 100644 --- a/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.test.tsx +++ b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.test.tsx @@ -29,7 +29,6 @@ import { MockStarredEntitiesApi, starredEntitiesApiRef, } from '@backstage/plugin-catalog-react'; -import { MockPluginProvider } from '@backstage/test-utils/alpha'; import { mockBreakpoint, MockStorageApi, @@ -133,7 +132,7 @@ describe('DefaultCatalogPage', () => { [starredEntitiesApiRef, new MockStarredEntitiesApi()], ]} > - {children} + {children} , { mountedRoutes: { diff --git a/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx index 04f39ee66c..fb9b282d57 100644 --- a/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx +++ b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx @@ -41,7 +41,8 @@ import { import React, { ReactNode } from 'react'; import { createComponentRouteRef } from '../../routes'; import { CatalogTable, CatalogTableRow } from '../CatalogTable'; -import { useCatalogPluginOptions } from '../../options'; +import { catalogTranslationRef } from '../../translation'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; /** * Props for root catalog pages. @@ -71,15 +72,14 @@ export function DefaultCatalogPage(props: DefaultCatalogPageProps) { const orgName = useApi(configApiRef).getOptionalString('organization.name') ?? 'Backstage'; const createComponentLink = useRouteRef(createComponentRouteRef); - - const { createButtonTitle } = useCatalogPluginOptions(); + const { t } = useTranslationRef(catalogTranslationRef); return ( - + All your software catalog entities diff --git a/plugins/catalog/src/plugin.ts b/plugins/catalog/src/plugin.ts index 711f52767a..3410984ec3 100644 --- a/plugins/catalog/src/plugin.ts +++ b/plugins/catalog/src/plugin.ts @@ -52,7 +52,6 @@ import { HasSystemsCardProps } from './components/HasSystemsCard'; import { RelatedEntitiesCardProps } from './components/RelatedEntitiesCard'; import { CatalogSearchResultListItemProps } from './components/CatalogSearchResultListItem'; import { rootRouteRef } from './routes'; -import { CatalogInputPluginOptions, CatalogPluginOptions } from './options'; /** @public */ export const catalogPlugin = createPlugin({ @@ -83,14 +82,6 @@ export const catalogPlugin = createPlugin({ viewTechDoc: viewTechDocRouteRef, createFromTemplate: createFromTemplateRouteRef, }, - __experimentalConfigure( - options?: CatalogInputPluginOptions, - ): CatalogPluginOptions { - const defaultOptions = { - createButtonTitle: 'Create', - }; - return { ...defaultOptions, ...options }; - }, }); /** @public */ diff --git a/plugins/catalog/src/options.ts b/plugins/catalog/src/translation.ts similarity index 61% rename from plugins/catalog/src/options.ts rename to plugins/catalog/src/translation.ts index 4ea6449a4b..2d1e3f2c8a 100644 --- a/plugins/catalog/src/options.ts +++ b/plugins/catalog/src/translation.ts @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Backstage Authors + * 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. @@ -14,16 +14,13 @@ * limitations under the License. */ -import { usePluginOptions } from '@backstage/core-plugin-api/alpha'; +import { createTranslationRef } from '@backstage/core-plugin-api/alpha'; -export type CatalogPluginOptions = { - createButtonTitle: string; -}; - -/** @ignore */ -export type CatalogInputPluginOptions = { - createButtonTitle: string; -}; - -export const useCatalogPluginOptions = () => - usePluginOptions(); +/** @alpha */ +export const catalogTranslationRef = createTranslationRef({ + id: 'catalog', + messages: { + catalog_page_title: `{{orgName}} Catalog`, + catalog_page_create_button_title: 'Create', + }, +}); From 959aa2a09fa0f441977472079ac2410b52a3545f Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sun, 24 Sep 2023 18:25:48 +0200 Subject: [PATCH 036/110] cost-insights: move hideTrendLine to config Signed-off-by: Patrik Oldsberg --- .changeset/ten-seals-wait.md | 5 ++++ plugins/cost-insights/api-report.md | 4 +-- plugins/cost-insights/config.d.ts | 5 ++++ .../CostOverviewCard.test.tsx | 5 +--- .../CostOverviewCard/CostOverviewChart.tsx | 4 +-- .../EntityCosts/EntityCost.test.tsx | 5 +--- plugins/cost-insights/src/hooks/useConfig.tsx | 11 +++++++ plugins/cost-insights/src/options.ts | 29 ------------------- plugins/cost-insights/src/plugin.ts | 12 -------- .../cost-insights/src/testUtils/providers.tsx | 1 + 10 files changed, 27 insertions(+), 54 deletions(-) create mode 100644 .changeset/ten-seals-wait.md delete mode 100644 plugins/cost-insights/src/options.ts diff --git a/.changeset/ten-seals-wait.md b/.changeset/ten-seals-wait.md new file mode 100644 index 0000000000..780422449c --- /dev/null +++ b/.changeset/ten-seals-wait.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-cost-insights': patch +--- + +The experimental plugin configuration has been removed. The trend line can now instead be hidden by setting `costInsights.hideTrendLine` to `true` in the configuration. diff --git a/plugins/cost-insights/api-report.md b/plugins/cost-insights/api-report.md index b37804c93d..11cdbd8141 100644 --- a/plugins/cost-insights/api-report.md +++ b/plugins/cost-insights/api-report.md @@ -242,6 +242,7 @@ export type ConfigContextProps = { icons: Icon[]; engineerCost: number; engineerThreshold: number; + hideTrendLine: boolean; currencies: Currency[]; }; @@ -326,8 +327,7 @@ const costInsightsPlugin: BackstagePlugin< growthAlerts: RouteRef; unlabeledDataflowAlerts: RouteRef; }, - {}, - CostInsightsInputPluginOptions + {} >; export { costInsightsPlugin }; export { costInsightsPlugin as plugin }; diff --git a/plugins/cost-insights/config.d.ts b/plugins/cost-insights/config.d.ts index 61a54f76e2..786d6f5a59 100644 --- a/plugins/cost-insights/config.d.ts +++ b/plugins/cost-insights/config.d.ts @@ -26,6 +26,11 @@ export interface Config { */ engineerThreshold?: number; + /** + * @visibility frontend + */ + hideTrendLine?: boolean; + /** * @visibility frontend */ diff --git a/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewCard.test.tsx b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewCard.test.tsx index d4fdc66bdb..2250392355 100644 --- a/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewCard.test.tsx +++ b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewCard.test.tsx @@ -15,7 +15,6 @@ */ import React from 'react'; import { fireEvent } from '@testing-library/react'; -import { MockPluginProvider } from '@backstage/test-utils/alpha'; import { renderInTestApp } from '@backstage/test-utils'; import { CostOverviewCard } from './CostOverviewCard'; import { Cost } from '@backstage/plugin-cost-insights-common'; @@ -45,9 +44,7 @@ function renderInContext(children: JSX.Element) { - - {children} - + {children} diff --git a/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewChart.tsx b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewChart.tsx index ce0623cc7e..2201dcc650 100644 --- a/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewChart.tsx +++ b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewChart.tsx @@ -47,7 +47,6 @@ import { groupByDate, trendFrom } from '../../utils/charts'; import { aggregationSort } from '../../utils/sort'; import { CostOverviewLegend } from './CostOverviewLegend'; import { TooltipRenderer } from '../../types'; -import { useCostInsightsOptions } from '../../options'; import { useConfig } from '../../hooks'; type CostOverviewChartProps = { @@ -65,7 +64,7 @@ export const CostOverviewChart = ({ }: CostOverviewChartProps) => { const theme = useTheme(); const styles = useStyles(theme); - const { baseCurrency } = useConfig(); + const { baseCurrency, hideTrendLine } = useConfig(); const data = { dailyCost: { @@ -134,7 +133,6 @@ export const CostOverviewChart = ({ ); }; - const { hideTrendLine } = useCostInsightsOptions(); const localizedTickFormatter = formatGraphValue(baseCurrency); return ( diff --git a/plugins/cost-insights/src/components/EntityCosts/EntityCost.test.tsx b/plugins/cost-insights/src/components/EntityCosts/EntityCost.test.tsx index 6eb3369b40..6ad7285ab9 100644 --- a/plugins/cost-insights/src/components/EntityCosts/EntityCost.test.tsx +++ b/plugins/cost-insights/src/components/EntityCosts/EntityCost.test.tsx @@ -14,7 +14,6 @@ * limitations under the License. */ import React from 'react'; -import { MockPluginProvider } from '@backstage/test-utils/alpha'; import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; import { changeOf, @@ -65,9 +64,7 @@ function renderInContext(children: JSX.Element) { - - {children} - + {children} diff --git a/plugins/cost-insights/src/hooks/useConfig.tsx b/plugins/cost-insights/src/hooks/useConfig.tsx index f42cea38c3..82c0ce26f5 100644 --- a/plugins/cost-insights/src/hooks/useConfig.tsx +++ b/plugins/cost-insights/src/hooks/useConfig.tsx @@ -72,6 +72,7 @@ export type ConfigContextProps = { icons: Icon[]; engineerCost: number; engineerThreshold: number; + hideTrendLine: boolean; currencies: Currency[]; }; @@ -86,6 +87,7 @@ const defaultState: ConfigContextProps = { icons: [], engineerCost: 0, engineerThreshold: EngineerThreshold, + hideTrendLine: false, currencies: defaultCurrencies, }; @@ -193,12 +195,20 @@ export const ConfigProvider = ({ children }: PropsWithChildren<{}>) => { ); } + function getHideTrendLine(): boolean { + return ( + c.getOptionalBoolean('costInsights.hideTrendLine') ?? + defaultState.hideTrendLine + ); + } + function getConfig() { const baseCurrency = getBaseCurrency(); const products = getProducts(); const metrics = getMetrics(); const engineerCost = getEngineerCost(); const engineerThreshold = getEngineerThreshold(); + const hideTrendLine = getHideTrendLine(); const icons = getIcons(); const currencies = getCurrencies(); @@ -212,6 +222,7 @@ export const ConfigProvider = ({ children }: PropsWithChildren<{}>) => { products, engineerCost, engineerThreshold, + hideTrendLine, icons, currencies, })); diff --git a/plugins/cost-insights/src/options.ts b/plugins/cost-insights/src/options.ts deleted file mode 100644 index acc977771d..0000000000 --- a/plugins/cost-insights/src/options.ts +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2020 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 { usePluginOptions } from '@backstage/core-plugin-api/alpha'; - -export type CostInsightsPluginOptions = { - hideTrendLine?: boolean; -}; - -/** @ignore */ -export type CostInsightsInputPluginOptions = { - hideTrendLine?: boolean; -}; - -export const useCostInsightsOptions = () => - usePluginOptions(); diff --git a/plugins/cost-insights/src/plugin.ts b/plugins/cost-insights/src/plugin.ts index c863c9e03a..04d58d1877 100644 --- a/plugins/cost-insights/src/plugin.ts +++ b/plugins/cost-insights/src/plugin.ts @@ -19,10 +19,6 @@ import { createRouteRef, createRoutableExtension, } from '@backstage/core-plugin-api'; -import { - CostInsightsInputPluginOptions, - CostInsightsPluginOptions, -} from './options'; export const rootRouteRef = createRouteRef({ id: 'cost-insights', @@ -45,14 +41,6 @@ export const costInsightsPlugin = createPlugin({ growthAlerts: projectGrowthAlertRef, unlabeledDataflowAlerts: unlabeledDataflowAlertRef, }, - __experimentalConfigure( - options?: CostInsightsInputPluginOptions, - ): CostInsightsPluginOptions { - const defaultOptions = { - hideTrendLine: false, - }; - return { ...defaultOptions, ...options }; - }, }); /** @public */ diff --git a/plugins/cost-insights/src/testUtils/providers.tsx b/plugins/cost-insights/src/testUtils/providers.tsx index 9522dfb702..5df1b2512f 100644 --- a/plugins/cost-insights/src/testUtils/providers.tsx +++ b/plugins/cost-insights/src/testUtils/providers.tsx @@ -96,6 +96,7 @@ export const MockConfigProvider = (props: MockConfigProviderProps) => { icons: [], engineerCost: 0, engineerThreshold: EngineerThreshold, + hideTrendLine: false, currencies: [], }; From 322bbcae24ed156060cb831f68794b9c85acfba2 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sun, 24 Sep 2023 18:30:11 +0200 Subject: [PATCH 037/110] core-plugin-api: remove exprerimental plugin options Signed-off-by: Patrik Oldsberg --- .changeset/angry-badgers-beg.md | 5 + .changeset/eighty-actors-type.md | 5 + .changeset/fresh-kangaroos-tap.md | 5 + packages/core-plugin-api/alpha-api-report.md | 18 ---- packages/core-plugin-api/api-report.md | 10 +- packages/core-plugin-api/src/alpha.ts | 1 - .../src/extensions/extensions.tsx | 5 +- .../src/plugin-options/index.ts | 18 ---- .../plugin-options/usePluginOptions.test.tsx | 53 ----------- .../src/plugin-options/usePluginOptions.tsx | 93 ------------------- .../core-plugin-api/src/plugin/Plugin.tsx | 31 +------ packages/core-plugin-api/src/plugin/types.ts | 5 +- .../frontend-app-api/src/wiring/createApp.tsx | 1 - packages/test-utils/alpha-api-report.md | 7 -- packages/test-utils/src/alpha.ts | 1 - .../src/testUtils/MockPluginProvider.tsx | 36 ------- 16 files changed, 24 insertions(+), 270 deletions(-) create mode 100644 .changeset/angry-badgers-beg.md create mode 100644 .changeset/eighty-actors-type.md create mode 100644 .changeset/fresh-kangaroos-tap.md delete mode 100644 packages/core-plugin-api/src/plugin-options/index.ts delete mode 100644 packages/core-plugin-api/src/plugin-options/usePluginOptions.test.tsx delete mode 100644 packages/core-plugin-api/src/plugin-options/usePluginOptions.tsx delete mode 100644 packages/test-utils/src/testUtils/MockPluginProvider.tsx diff --git a/.changeset/angry-badgers-beg.md b/.changeset/angry-badgers-beg.md new file mode 100644 index 0000000000..38952aef98 --- /dev/null +++ b/.changeset/angry-badgers-beg.md @@ -0,0 +1,5 @@ +--- +'@backstage/frontend-app-api': patch +--- + +Internal update for removal of experimental plugin configuration API. diff --git a/.changeset/eighty-actors-type.md b/.changeset/eighty-actors-type.md new file mode 100644 index 0000000000..5c55a7b0c6 --- /dev/null +++ b/.changeset/eighty-actors-type.md @@ -0,0 +1,5 @@ +--- +'@backstage/test-utils': patch +--- + +Removed the alpha `MockPluginProvider` export since the plugin configuration API has been removed. diff --git a/.changeset/fresh-kangaroos-tap.md b/.changeset/fresh-kangaroos-tap.md new file mode 100644 index 0000000000..5ac4d184eb --- /dev/null +++ b/.changeset/fresh-kangaroos-tap.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-plugin-api': minor +--- + +Removed the exprimental plugin configuration API. The `__experimentalReconfigure()` from the plugin options as well as the `__experimentalConfigure()` method on plugin instances have both been removed. diff --git a/packages/core-plugin-api/alpha-api-report.md b/packages/core-plugin-api/alpha-api-report.md index d50bb0abd6..ba3583142f 100644 --- a/packages/core-plugin-api/alpha-api-report.md +++ b/packages/core-plugin-api/alpha-api-report.md @@ -4,9 +4,7 @@ ```ts import { ApiRef } from '@backstage/core-plugin-api'; -import { BackstagePlugin } from '@backstage/core-plugin-api'; import { Observable } from '@backstage/types'; -import { ReactNode } from 'react'; import { TranslationMessages as TranslationMessages_2 } from '@backstage/core-plugin-api/alpha'; import { TranslationRef as TranslationRef_2 } from '@backstage/core-plugin-api/alpha'; @@ -74,17 +72,6 @@ export function createTranslationResource< options: TranslationResourceOptions, ): TranslationResource; -// @alpha -export interface PluginOptionsProviderProps { - // (undocumented) - children: ReactNode; - // (undocumented) - plugin?: BackstagePlugin; -} - -// @alpha -export const PluginProvider: (props: PluginOptionsProviderProps) => JSX.Element; - // @alpha (undocumented) export type TranslationApi = { getTranslation< @@ -245,11 +232,6 @@ export type TranslationSnapshot< t: TranslationFunction; }; -// @alpha -export function usePluginOptions< - TPluginOptions extends {} = {}, ->(): TPluginOptions; - // @alpha (undocumented) export const useTranslationRef: < TMessages extends { diff --git a/packages/core-plugin-api/api-report.md b/packages/core-plugin-api/api-report.md index 930f1f979d..7873b23f13 100644 --- a/packages/core-plugin-api/api-report.md +++ b/packages/core-plugin-api/api-report.md @@ -222,7 +222,7 @@ export type BackstageIdentityResponse = { export type BackstagePlugin< Routes extends AnyRoutes = {}, ExternalRoutes extends AnyExternalRoutes = {}, - PluginInputOptions extends {} = {}, + _Ignored extends {} = {}, > = { getId(): string; getApis(): Iterable; @@ -230,7 +230,6 @@ export type BackstagePlugin< provide(extension: Extension): T; routes: Routes; externalRoutes: ExternalRoutes; - __experimentalReconfigure(options: PluginInputOptions): void; }; // @public @@ -318,10 +317,9 @@ export function createExternalRouteRef< export function createPlugin< Routes extends AnyRoutes = {}, ExternalRoutes extends AnyExternalRoutes = {}, - PluginInputOptions extends {} = {}, >( - config: PluginConfig, -): BackstagePlugin; + config: PluginConfig, +): BackstagePlugin; // @public export function createReactExtension< @@ -647,14 +645,12 @@ export type PendingOAuthRequest = { export type PluginConfig< Routes extends AnyRoutes, ExternalRoutes extends AnyExternalRoutes, - PluginInputOptions extends {}, > = { id: string; apis?: Iterable; routes?: Routes; externalRoutes?: ExternalRoutes; featureFlags?: PluginFeatureFlagConfig[]; - __experimentalConfigure?(options?: PluginInputOptions): {}; }; // @public diff --git a/packages/core-plugin-api/src/alpha.ts b/packages/core-plugin-api/src/alpha.ts index 505fd9b818..ebcbcf34c0 100644 --- a/packages/core-plugin-api/src/alpha.ts +++ b/packages/core-plugin-api/src/alpha.ts @@ -14,6 +14,5 @@ * limitations under the License. */ -export * from './plugin-options'; export * from './translation'; export * from './apis/alpha'; diff --git a/packages/core-plugin-api/src/extensions/extensions.tsx b/packages/core-plugin-api/src/extensions/extensions.tsx index a9a3127aee..b94354fa2c 100644 --- a/packages/core-plugin-api/src/extensions/extensions.tsx +++ b/packages/core-plugin-api/src/extensions/extensions.tsx @@ -21,7 +21,6 @@ import { RouteRef, useRouteRef } from '../routing'; import { attachComponentData } from './componentData'; import { Extension, BackstagePlugin } from '../plugin'; import { PluginErrorBoundary } from './PluginErrorBoundary'; -import { PluginProvider } from '../plugin-options'; import { routableExtensionRenderedEvent } from '../analytics/Tracker'; /** @@ -258,9 +257,7 @@ export function createReactExtension< ...(mountPoint && { routeRef: mountPoint.id }), }} > - - - + diff --git a/packages/core-plugin-api/src/plugin-options/index.ts b/packages/core-plugin-api/src/plugin-options/index.ts deleted file mode 100644 index 1737a1c836..0000000000 --- a/packages/core-plugin-api/src/plugin-options/index.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2020 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 { usePluginOptions, PluginProvider } from './usePluginOptions'; -export type { PluginOptionsProviderProps } from './usePluginOptions'; diff --git a/packages/core-plugin-api/src/plugin-options/usePluginOptions.test.tsx b/packages/core-plugin-api/src/plugin-options/usePluginOptions.test.tsx deleted file mode 100644 index 96691d503b..0000000000 --- a/packages/core-plugin-api/src/plugin-options/usePluginOptions.test.tsx +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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 React from 'react'; -import { renderHook } from '@testing-library/react-hooks'; -import { usePluginOptions, PluginProvider } from './usePluginOptions'; -import { createPlugin } from '../plugin'; - -describe('usePluginOptions', () => { - it('should provide a versioned value to hook', () => { - type TestInputPluginOptions = { - 'key-1': string; - }; - - type TestPluginOptions = { - 'key-1': string; - 'key-2': string; - }; - - const plugin = createPlugin({ - id: 'my-plugin', - __experimentalConfigure(_: TestInputPluginOptions): TestPluginOptions { - return { 'key-1': 'value-1', 'key-2': 'value-2' }; - }, - }); - - const rendered = renderHook(() => usePluginOptions(), { - wrapper: ({ children }: React.PropsWithChildren<{}>) => ( - {children} - ), - }); - - const config = rendered.result.current; - - expect(config).toEqual({ - 'key-1': 'value-1', - 'key-2': 'value-2', - }); - }); -}); diff --git a/packages/core-plugin-api/src/plugin-options/usePluginOptions.tsx b/packages/core-plugin-api/src/plugin-options/usePluginOptions.tsx deleted file mode 100644 index 8b3f7c109c..0000000000 --- a/packages/core-plugin-api/src/plugin-options/usePluginOptions.tsx +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2020 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 { - createVersionedContext, - createVersionedValueMap, - useVersionedContext, -} from '@backstage/version-bridge'; -import { BackstagePlugin } from '@backstage/core-plugin-api'; -import React, { ReactNode } from 'react'; - -const contextKey: string = 'plugin-context'; - -/** - * Properties for the PluginProvider component. - * - * @alpha - */ -export interface PluginOptionsProviderProps { - children: ReactNode; - plugin?: BackstagePlugin; -} - -/** - * Contains the plugin configuration. - * - * @alpha - */ -export const PluginProvider = ( - props: PluginOptionsProviderProps, -): JSX.Element => { - const { children, plugin } = props; - - const { Provider } = createVersionedContext<{ - 1: { plugin: BackstagePlugin | undefined }; - }>(contextKey); - - return ( - - {children} - - ); -}; - -/** - * Grab the current entity from the context, throws if the entity has not yet been loaded - * or is not available. - * - * @alpha - */ -export function usePluginOptions< - TPluginOptions extends {} = {}, ->(): TPluginOptions { - const versionedHolder = useVersionedContext<{ 1: TPluginOptions }>( - contextKey, - ); - - if (!versionedHolder) { - throw new Error('Plugin Options context is not available'); - } - - const value = versionedHolder.atVersion(1); - if (!value) { - throw new Error('Plugin Options v1 is not available'); - } - - return ( - value as unknown as { - plugin: { - getPluginOptions(): {}; - }; - } - ).plugin.getPluginOptions() as TPluginOptions; -} diff --git a/packages/core-plugin-api/src/plugin/Plugin.tsx b/packages/core-plugin-api/src/plugin/Plugin.tsx index da26cd4db0..d97554b27b 100644 --- a/packages/core-plugin-api/src/plugin/Plugin.tsx +++ b/packages/core-plugin-api/src/plugin/Plugin.tsx @@ -30,18 +30,9 @@ import { AnyApiFactory } from '../apis'; export class PluginImpl< Routes extends AnyRoutes, ExternalRoutes extends AnyExternalRoutes, - PluginInputOptions extends {}, -> implements BackstagePlugin +> implements BackstagePlugin { - constructor( - private readonly config: PluginConfig< - Routes, - ExternalRoutes, - PluginInputOptions - >, - ) {} - - private options: {} | undefined = undefined; + constructor(private readonly config: PluginConfig) {} getId(): string { return this.config.id; @@ -67,19 +58,6 @@ export class PluginImpl< return extension.expose(this); } - __experimentalReconfigure(options: PluginInputOptions): void { - if (this.config.__experimentalConfigure) { - this.options = this.config.__experimentalConfigure(options); - } - } - - getPluginOptions(): {} { - if (this.config.__experimentalConfigure && !this.options) { - this.options = this.config.__experimentalConfigure(); - } - return this.options ?? {}; - } - toString() { return `plugin{${this.config.id}}`; } @@ -94,9 +72,8 @@ export class PluginImpl< export function createPlugin< Routes extends AnyRoutes = {}, ExternalRoutes extends AnyExternalRoutes = {}, - PluginInputOptions extends {} = {}, >( - config: PluginConfig, -): BackstagePlugin { + config: PluginConfig, +): BackstagePlugin { return new PluginImpl(config); } diff --git a/packages/core-plugin-api/src/plugin/types.ts b/packages/core-plugin-api/src/plugin/types.ts index 37ce6c9e7c..3ba7706e16 100644 --- a/packages/core-plugin-api/src/plugin/types.ts +++ b/packages/core-plugin-api/src/plugin/types.ts @@ -52,7 +52,7 @@ export type AnyExternalRoutes = { [name: string]: ExternalRouteRef }; export type BackstagePlugin< Routes extends AnyRoutes = {}, ExternalRoutes extends AnyExternalRoutes = {}, - PluginInputOptions extends {} = {}, + _Ignored extends {} = {}, > = { getId(): string; getApis(): Iterable; @@ -63,7 +63,6 @@ export type BackstagePlugin< provide(extension: Extension): T; routes: Routes; externalRoutes: ExternalRoutes; - __experimentalReconfigure(options: PluginInputOptions): void; }; /** @@ -84,14 +83,12 @@ export type PluginFeatureFlagConfig = { export type PluginConfig< Routes extends AnyRoutes, ExternalRoutes extends AnyExternalRoutes, - PluginInputOptions extends {}, > = { id: string; apis?: Iterable; routes?: Routes; externalRoutes?: ExternalRoutes; featureFlags?: PluginFeatureFlagConfig[]; - __experimentalConfigure?(options?: PluginInputOptions): {}; }; /** diff --git a/packages/frontend-app-api/src/wiring/createApp.tsx b/packages/frontend-app-api/src/wiring/createApp.tsx index 462bfcdccc..12965f9bdf 100644 --- a/packages/frontend-app-api/src/wiring/createApp.tsx +++ b/packages/frontend-app-api/src/wiring/createApp.tsx @@ -314,7 +314,6 @@ function toLegacyPlugin(plugin: BackstagePlugin): LegacyBackstagePlugin { getApis: notImplemented, getFeatureFlags: notImplemented, provide: notImplemented, - __experimentalReconfigure: notImplemented, }; } diff --git a/packages/test-utils/alpha-api-report.md b/packages/test-utils/alpha-api-report.md index 4a9fd2e5a4..945c754f83 100644 --- a/packages/test-utils/alpha-api-report.md +++ b/packages/test-utils/alpha-api-report.md @@ -4,17 +4,10 @@ ```ts import { Observable } from '@backstage/types'; -import { PropsWithChildren } from 'react'; -import { default as React_2 } from 'react'; import { TranslationApi } from '@backstage/core-plugin-api/alpha'; import { TranslationRef } from '@backstage/core-plugin-api/alpha'; import { TranslationSnapshot } from '@backstage/core-plugin-api/alpha'; -// @alpha -export const MockPluginProvider: ({ - children, -}: PropsWithChildren<{}>) => React_2.JSX.Element; - // @alpha (undocumented) export class MockTranslationApi implements TranslationApi { // (undocumented) diff --git a/packages/test-utils/src/alpha.ts b/packages/test-utils/src/alpha.ts index c6801993bc..2077ad3586 100644 --- a/packages/test-utils/src/alpha.ts +++ b/packages/test-utils/src/alpha.ts @@ -14,5 +14,4 @@ * limitations under the License. */ -export * from './testUtils/MockPluginProvider'; export * from './testUtils/apis/TranslationApi'; diff --git a/packages/test-utils/src/testUtils/MockPluginProvider.tsx b/packages/test-utils/src/testUtils/MockPluginProvider.tsx deleted file mode 100644 index 25442ae267..0000000000 --- a/packages/test-utils/src/testUtils/MockPluginProvider.tsx +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2020 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, { PropsWithChildren } from 'react'; -import { PluginProvider } from '@backstage/core-plugin-api/alpha'; -import { createPlugin } from '@backstage/core-plugin-api'; - -/** - * Mock for PluginProvider to use in unit tests - * @alpha - */ -export const MockPluginProvider = ({ children }: PropsWithChildren<{}>) => { - type TestInputPluginOptions = {}; - type TestPluginOptions = {}; - const plugin = createPlugin({ - id: 'my-plugin', - __experimentalConfigure(_: TestInputPluginOptions): TestPluginOptions { - return {}; - }, - }); - - return {children}; -}; From df97115aac67cd3379f335980afe69b9222daa07 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 25 Sep 2023 09:52:46 +0200 Subject: [PATCH 038/110] plugins: update API report to match new BackstagePlugin type Signed-off-by: Patrik Oldsberg --- plugins/adr/api-report.md | 1 - plugins/airbrake/api-report.md | 1 - plugins/allure/api-report.md | 1 - plugins/analytics-module-ga/api-report.md | 2 +- plugins/apache-airflow/api-report.md | 1 - plugins/api-docs/api-report.md | 3 +-- plugins/apollo-explorer/api-report.md | 1 - plugins/azure-devops/api-report.md | 2 +- plugins/azure-sites/api-report.md | 1 - plugins/badges/api-report.md | 2 +- plugins/bazaar/api-report.md | 1 - plugins/bitrise/api-report.md | 2 +- plugins/catalog-graph/api-report.md | 3 +-- plugins/catalog-import/api-report.md | 1 - plugins/catalog-unprocessed-entities/api-report.md | 1 - plugins/cicd-statistics/api-report.md | 1 - plugins/circleci/api-report.md | 2 +- plugins/cloudbuild/api-report.md | 1 - plugins/code-climate/api-report.md | 1 - plugins/code-coverage/api-report.md | 1 - plugins/codescene/api-report.md | 1 - plugins/config-schema/api-report.md | 1 - plugins/devtools/api-report.md | 1 - plugins/dynatrace/api-report.md | 2 +- plugins/entity-feedback/api-report.md | 1 - plugins/entity-validation/api-report.md | 1 - plugins/example-todo-list/api-report.md | 1 - plugins/explore/api-report.md | 3 +-- plugins/firehydrant/api-report.md | 1 - plugins/fossa/api-report.md | 1 - plugins/gcalendar/api-report.md | 1 - plugins/gcp-projects/api-report.md | 1 - plugins/git-release-manager/api-report.md | 1 - plugins/github-actions/api-report.md | 1 - plugins/github-deployments/api-report.md | 2 +- plugins/github-issues/api-report.md | 1 - plugins/gitops-profiles/api-report.md | 1 - plugins/gocd/api-report.md | 2 +- plugins/graphiql/api-report.md | 2 +- plugins/graphql-voyager/api-report.md | 1 - plugins/home/api-report.md | 1 - plugins/ilert/api-report.md | 1 - plugins/jenkins/api-report.md | 1 - plugins/kafka/api-report.md | 1 - plugins/kubernetes/api-report.md | 1 - plugins/lighthouse/api-report.md | 1 - plugins/linguist/api-report.md | 2 +- plugins/newrelic-dashboard/api-report.md | 1 - plugins/newrelic/api-report.md | 1 - plugins/nomad/api-report.md | 1 - plugins/octopus-deploy/api-report.md | 2 +- plugins/opencost/api-report.md | 1 - plugins/org/api-report.md | 3 +-- plugins/pagerduty/api-report.md | 2 +- plugins/periskop/api-report.md | 2 +- plugins/playlist/api-report.md | 1 - plugins/puppetdb/api-report.md | 2 +- plugins/rollbar/api-report.md | 1 - plugins/scaffolder/api-report.md | 3 +-- plugins/search/api-report.md | 1 - plugins/sentry/api-report.md | 1 - plugins/shortcuts/api-report.md | 2 +- plugins/sonarqube/api-report.md | 2 +- plugins/splunk-on-call/api-report.md | 1 - plugins/stack-overflow/api-report.md | 2 +- plugins/stackstorm/api-report.md | 1 - plugins/tech-insights/api-report.md | 1 - plugins/tech-radar/api-report.md | 1 - plugins/techdocs-module-addons-contrib/api-report.md | 2 +- plugins/techdocs/api-report.md | 1 - plugins/todo/api-report.md | 1 - plugins/user-settings/api-report.md | 1 - plugins/vault/api-report.md | 2 +- plugins/xcmetrics/api-report.md | 1 - 74 files changed, 24 insertions(+), 79 deletions(-) diff --git a/plugins/adr/api-report.md b/plugins/adr/api-report.md index 6ed7b68196..9ce5834574 100644 --- a/plugins/adr/api-report.md +++ b/plugins/adr/api-report.md @@ -72,7 +72,6 @@ export const adrPlugin: BackstagePlugin< { root: RouteRef; }, - {}, {} >; diff --git a/plugins/airbrake/api-report.md b/plugins/airbrake/api-report.md index a04d57d7e9..66f9b19bc8 100644 --- a/plugins/airbrake/api-report.md +++ b/plugins/airbrake/api-report.md @@ -13,7 +13,6 @@ export const airbrakePlugin: BackstagePlugin< { root: RouteRef; }, - {}, {} >; diff --git a/plugins/allure/api-report.md b/plugins/allure/api-report.md index a192851f26..69bb740271 100644 --- a/plugins/allure/api-report.md +++ b/plugins/allure/api-report.md @@ -18,7 +18,6 @@ export const allurePlugin: BackstagePlugin< { root: RouteRef; }, - {}, {} >; diff --git a/plugins/analytics-module-ga/api-report.md b/plugins/analytics-module-ga/api-report.md index f28c919f33..1846211e72 100644 --- a/plugins/analytics-module-ga/api-report.md +++ b/plugins/analytics-module-ga/api-report.md @@ -10,7 +10,7 @@ import { Config } from '@backstage/config'; import { IdentityApi } from '@backstage/core-plugin-api'; // @public @deprecated (undocumented) -export const analyticsModuleGA: BackstagePlugin<{}, {}, {}>; +export const analyticsModuleGA: BackstagePlugin<{}, {}>; // @public export class GoogleAnalytics implements AnalyticsApi { diff --git a/plugins/apache-airflow/api-report.md b/plugins/apache-airflow/api-report.md index be2a208bd4..922ad4e868 100644 --- a/plugins/apache-airflow/api-report.md +++ b/plugins/apache-airflow/api-report.md @@ -22,7 +22,6 @@ export const apacheAirflowPlugin: BackstagePlugin< { root: RouteRef; }, - {}, {} >; ``` diff --git a/plugins/api-docs/api-report.md b/plugins/api-docs/api-report.md index 59d490a1fe..2254bf96cd 100644 --- a/plugins/api-docs/api-report.md +++ b/plugins/api-docs/api-report.md @@ -54,8 +54,7 @@ const apiDocsPlugin: BackstagePlugin< }, { registerApi: ExternalRouteRef; - }, - {} + } >; export { apiDocsPlugin }; export { apiDocsPlugin as plugin }; diff --git a/plugins/apollo-explorer/api-report.md b/plugins/apollo-explorer/api-report.md index 2dd6c14a90..7d06876e89 100644 --- a/plugins/apollo-explorer/api-report.md +++ b/plugins/apollo-explorer/api-report.md @@ -38,7 +38,6 @@ export const apolloExplorerPlugin: BackstagePlugin< { root: RouteRef; }, - {}, {} >; ``` diff --git a/plugins/azure-devops/api-report.md b/plugins/azure-devops/api-report.md index 2c916ec33b..6b33762639 100644 --- a/plugins/azure-devops/api-report.md +++ b/plugins/azure-devops/api-report.md @@ -162,7 +162,7 @@ export class AzureDevOpsClient implements AzureDevOpsApi { } // @public (undocumented) -export const azureDevOpsPlugin: BackstagePlugin<{}, {}, {}>; +export const azureDevOpsPlugin: BackstagePlugin<{}, {}>; // @public (undocumented) export const AzurePullRequestsIcon: ( diff --git a/plugins/azure-sites/api-report.md b/plugins/azure-sites/api-report.md index bec89e17bc..abc10ec723 100644 --- a/plugins/azure-sites/api-report.md +++ b/plugins/azure-sites/api-report.md @@ -49,7 +49,6 @@ export const azureSitesPlugin: BackstagePlugin< { entityContent: RouteRef; }, - {}, {} >; diff --git a/plugins/badges/api-report.md b/plugins/badges/api-report.md index e73a887316..c32b901058 100644 --- a/plugins/badges/api-report.md +++ b/plugins/badges/api-report.md @@ -9,7 +9,7 @@ import { BackstagePlugin } from '@backstage/core-plugin-api'; import { JSX as JSX_2 } from 'react'; // @public (undocumented) -export const badgesPlugin: BackstagePlugin<{}, {}, {}>; +export const badgesPlugin: BackstagePlugin<{}, {}>; // @public (undocumented) export const EntityBadgesDialog: (props: { diff --git a/plugins/bazaar/api-report.md b/plugins/bazaar/api-report.md index 282983b378..ba0396f81e 100644 --- a/plugins/bazaar/api-report.md +++ b/plugins/bazaar/api-report.md @@ -41,7 +41,6 @@ export const bazaarPlugin: BackstagePlugin< { root: RouteRef; }, - {}, {} >; diff --git a/plugins/bitrise/api-report.md b/plugins/bitrise/api-report.md index 7f2e44f04f..cb68d79c51 100644 --- a/plugins/bitrise/api-report.md +++ b/plugins/bitrise/api-report.md @@ -13,7 +13,7 @@ import { JSX as JSX_2 } from 'react'; export const BITRISE_APP_ANNOTATION = 'bitrise.io/app'; // @public (undocumented) -export const bitrisePlugin: BackstagePlugin<{}, {}, {}>; +export const bitrisePlugin: BackstagePlugin<{}, {}>; // @public (undocumented) export const EntityBitriseContent: () => JSX_2.Element; diff --git a/plugins/catalog-graph/api-report.md b/plugins/catalog-graph/api-report.md index ce56245c49..98a68d8aa2 100644 --- a/plugins/catalog-graph/api-report.md +++ b/plugins/catalog-graph/api-report.md @@ -53,8 +53,7 @@ export const catalogGraphPlugin: BackstagePlugin< }, true >; - }, - {} + } >; // @public diff --git a/plugins/catalog-import/api-report.md b/plugins/catalog-import/api-report.md index 7397bfad1d..a513cfe87a 100644 --- a/plugins/catalog-import/api-report.md +++ b/plugins/catalog-import/api-report.md @@ -134,7 +134,6 @@ const catalogImportPlugin: BackstagePlugin< { importPage: RouteRef; }, - {}, {} >; export { catalogImportPlugin }; diff --git a/plugins/catalog-unprocessed-entities/api-report.md b/plugins/catalog-unprocessed-entities/api-report.md index 3ded42785a..cc4d6bba88 100644 --- a/plugins/catalog-unprocessed-entities/api-report.md +++ b/plugins/catalog-unprocessed-entities/api-report.md @@ -34,7 +34,6 @@ export const catalogUnprocessedEntitiesPlugin: BackstagePlugin< { root: RouteRef; }, - {}, {} >; diff --git a/plugins/cicd-statistics/api-report.md b/plugins/cicd-statistics/api-report.md index b0966aa281..70895d6a63 100644 --- a/plugins/cicd-statistics/api-report.md +++ b/plugins/cicd-statistics/api-report.md @@ -85,7 +85,6 @@ export const cicdStatisticsPlugin: BackstagePlugin< { entityContent: RouteRef; }, - {}, {} >; diff --git a/plugins/circleci/api-report.md b/plugins/circleci/api-report.md index d706115610..3bb8d4b6f9 100644 --- a/plugins/circleci/api-report.md +++ b/plugins/circleci/api-report.md @@ -63,7 +63,7 @@ export const circleCIApiRef: ApiRef; export const circleCIBuildRouteRef: SubRouteRef>; // @public (undocumented) -const circleCIPlugin: BackstagePlugin<{}, {}, {}>; +const circleCIPlugin: BackstagePlugin<{}, {}>; export { circleCIPlugin }; export { circleCIPlugin as plugin }; diff --git a/plugins/cloudbuild/api-report.md b/plugins/cloudbuild/api-report.md index dc2aacbc18..3fbb15000d 100644 --- a/plugins/cloudbuild/api-report.md +++ b/plugins/cloudbuild/api-report.md @@ -104,7 +104,6 @@ const cloudbuildPlugin: BackstagePlugin< { entityContent: RouteRef; }, - {}, {} >; export { cloudbuildPlugin }; diff --git a/plugins/code-climate/api-report.md b/plugins/code-climate/api-report.md index 32359f663f..8243cada75 100644 --- a/plugins/code-climate/api-report.md +++ b/plugins/code-climate/api-report.md @@ -42,7 +42,6 @@ export const codeClimatePlugin: BackstagePlugin< { root: RouteRef; }, - {}, {} >; diff --git a/plugins/code-coverage/api-report.md b/plugins/code-coverage/api-report.md index 5dcb5fcfd1..152cc93103 100644 --- a/plugins/code-coverage/api-report.md +++ b/plugins/code-coverage/api-report.md @@ -14,7 +14,6 @@ export const codeCoveragePlugin: BackstagePlugin< { root: RouteRef; }, - {}, {} >; diff --git a/plugins/codescene/api-report.md b/plugins/codescene/api-report.md index 662968d3c9..99eb2b6256 100644 --- a/plugins/codescene/api-report.md +++ b/plugins/codescene/api-report.md @@ -24,7 +24,6 @@ export const codescenePlugin: BackstagePlugin< projectId: string; }>; }, - {}, {} >; diff --git a/plugins/config-schema/api-report.md b/plugins/config-schema/api-report.md index 95d352d1b7..16630ae8d0 100644 --- a/plugins/config-schema/api-report.md +++ b/plugins/config-schema/api-report.md @@ -29,7 +29,6 @@ export const configSchemaPlugin: BackstagePlugin< { root: RouteRef; }, - {}, {} >; diff --git a/plugins/devtools/api-report.md b/plugins/devtools/api-report.md index f0a9280162..21754d7c1e 100644 --- a/plugins/devtools/api-report.md +++ b/plugins/devtools/api-report.md @@ -36,7 +36,6 @@ export const devToolsPlugin: BackstagePlugin< { root: RouteRef; }, - {}, {} >; diff --git a/plugins/dynatrace/api-report.md b/plugins/dynatrace/api-report.md index 0f25fc3108..f78b4060fd 100644 --- a/plugins/dynatrace/api-report.md +++ b/plugins/dynatrace/api-report.md @@ -10,7 +10,7 @@ import { Entity } from '@backstage/catalog-model'; import { JSX as JSX_2 } from 'react'; // @public -export const dynatracePlugin: BackstagePlugin<{}, {}, {}>; +export const dynatracePlugin: BackstagePlugin<{}, {}>; // @public export const DynatraceTab: () => JSX_2.Element; diff --git a/plugins/entity-feedback/api-report.md b/plugins/entity-feedback/api-report.md index d61394ab9a..27e56e5282 100644 --- a/plugins/entity-feedback/api-report.md +++ b/plugins/entity-feedback/api-report.md @@ -70,7 +70,6 @@ export const entityFeedbackPlugin: BackstagePlugin< { root: RouteRef; }, - {}, {} >; diff --git a/plugins/entity-validation/api-report.md b/plugins/entity-validation/api-report.md index 48b309cfaa..9d69458ed0 100644 --- a/plugins/entity-validation/api-report.md +++ b/plugins/entity-validation/api-report.md @@ -20,7 +20,6 @@ export const entityValidationPlugin: BackstagePlugin< { root: RouteRef; }, - {}, {} >; diff --git a/plugins/example-todo-list/api-report.md b/plugins/example-todo-list/api-report.md index 1b7aa49a19..2feeeb903d 100644 --- a/plugins/example-todo-list/api-report.md +++ b/plugins/example-todo-list/api-report.md @@ -17,7 +17,6 @@ export const todoListPlugin: BackstagePlugin< { root: RouteRef; }, - {}, {} >; diff --git a/plugins/explore/api-report.md b/plugins/explore/api-report.md index 193efb044d..d32a133685 100644 --- a/plugins/explore/api-report.md +++ b/plugins/explore/api-report.md @@ -99,8 +99,7 @@ const explorePlugin: BackstagePlugin< }, true >; - }, - {} + } >; export { explorePlugin }; export { explorePlugin as plugin }; diff --git a/plugins/firehydrant/api-report.md b/plugins/firehydrant/api-report.md index 76ccd8f019..9eeac41576 100644 --- a/plugins/firehydrant/api-report.md +++ b/plugins/firehydrant/api-report.md @@ -18,7 +18,6 @@ export const firehydrantPlugin: BackstagePlugin< { root: RouteRef; }, - {}, {} >; diff --git a/plugins/fossa/api-report.md b/plugins/fossa/api-report.md index ac76ff6af6..6be878d434 100644 --- a/plugins/fossa/api-report.md +++ b/plugins/fossa/api-report.md @@ -31,7 +31,6 @@ export const fossaPlugin: BackstagePlugin< { fossaOverview: RouteRef; }, - {}, {} >; ``` diff --git a/plugins/gcalendar/api-report.md b/plugins/gcalendar/api-report.md index 3f1d42d239..f1f505fc9a 100644 --- a/plugins/gcalendar/api-report.md +++ b/plugins/gcalendar/api-report.md @@ -51,7 +51,6 @@ export const gcalendarPlugin: BackstagePlugin< { root: RouteRef; }, - {}, {} >; diff --git a/plugins/gcp-projects/api-report.md b/plugins/gcp-projects/api-report.md index fd156687c0..e6938485fc 100644 --- a/plugins/gcp-projects/api-report.md +++ b/plugins/gcp-projects/api-report.md @@ -48,7 +48,6 @@ const gcpProjectsPlugin: BackstagePlugin< { root: RouteRef; }, - {}, {} >; export { gcpProjectsPlugin }; diff --git a/plugins/git-release-manager/api-report.md b/plugins/git-release-manager/api-report.md index a3215041f0..3e4c0847a7 100644 --- a/plugins/git-release-manager/api-report.md +++ b/plugins/git-release-manager/api-report.md @@ -263,7 +263,6 @@ export const gitReleaseManagerPlugin: BackstagePlugin< { root: RouteRef; }, - {}, {} >; diff --git a/plugins/github-actions/api-report.md b/plugins/github-actions/api-report.md index e7c6114c93..887556f431 100644 --- a/plugins/github-actions/api-report.md +++ b/plugins/github-actions/api-report.md @@ -177,7 +177,6 @@ const githubActionsPlugin: BackstagePlugin< { entityContent: RouteRef; }, - {}, {} >; export { githubActionsPlugin }; diff --git a/plugins/github-deployments/api-report.md b/plugins/github-deployments/api-report.md index 669bcd74ba..26bb108d86 100644 --- a/plugins/github-deployments/api-report.md +++ b/plugins/github-deployments/api-report.md @@ -43,7 +43,7 @@ export type GithubDeployment = { }; // @public (undocumented) -export const githubDeploymentsPlugin: BackstagePlugin<{}, {}, {}>; +export const githubDeploymentsPlugin: BackstagePlugin<{}, {}>; // @public (undocumented) export const GithubDeploymentsTable: { diff --git a/plugins/github-issues/api-report.md b/plugins/github-issues/api-report.md index 3c7b616f82..0efa863a01 100644 --- a/plugins/github-issues/api-report.md +++ b/plugins/github-issues/api-report.md @@ -52,7 +52,6 @@ export const githubIssuesPlugin: BackstagePlugin< { root: RouteRef; }, - {}, {} >; diff --git a/plugins/gitops-profiles/api-report.md b/plugins/gitops-profiles/api-report.md index 3dc3c9add2..97f3a9864b 100644 --- a/plugins/gitops-profiles/api-report.md +++ b/plugins/gitops-profiles/api-report.md @@ -124,7 +124,6 @@ const gitopsProfilesPlugin: BackstagePlugin< }>; createPage: RouteRef; }, - {}, {} >; export { gitopsProfilesPlugin }; diff --git a/plugins/gocd/api-report.md b/plugins/gocd/api-report.md index df93b5f2eb..de2c76e06b 100644 --- a/plugins/gocd/api-report.md +++ b/plugins/gocd/api-report.md @@ -15,7 +15,7 @@ export const EntityGoCdContent: () => JSX.Element; export const GOCD_PIPELINES_ANNOTATION = 'gocd.org/pipelines'; // @public -export const gocdPlugin: BackstagePlugin<{}, {}, {}>; +export const gocdPlugin: BackstagePlugin<{}, {}>; // @public export const isGoCdAvailable: (entity: Entity) => boolean; diff --git a/plugins/graphiql/api-report.md b/plugins/graphiql/api-report.md index cbecc37006..984b90ae88 100644 --- a/plugins/graphiql/api-report.md +++ b/plugins/graphiql/api-report.md @@ -44,7 +44,7 @@ export const GraphiQLIcon: IconComponent; export const GraphiQLPage: () => JSX_2.Element; // @public (undocumented) -const graphiqlPlugin: BackstagePlugin<{}, {}, {}>; +const graphiqlPlugin: BackstagePlugin<{}, {}>; export { graphiqlPlugin }; export { graphiqlPlugin as plugin }; diff --git a/plugins/graphql-voyager/api-report.md b/plugins/graphql-voyager/api-report.md index 257a8ca7b7..e926bbd193 100644 --- a/plugins/graphql-voyager/api-report.md +++ b/plugins/graphql-voyager/api-report.md @@ -59,7 +59,6 @@ export const graphqlVoyagerPlugin: BackstagePlugin< { root: RouteRef; }, - {}, {} >; diff --git a/plugins/home/api-report.md b/plugins/home/api-report.md index 450bc054fa..497b11224d 100644 --- a/plugins/home/api-report.md +++ b/plugins/home/api-report.md @@ -137,7 +137,6 @@ export const homePlugin: BackstagePlugin< { root: RouteRef; }, - {}, {} >; diff --git a/plugins/ilert/api-report.md b/plugins/ilert/api-report.md index b2081e049e..821a3a6bd0 100644 --- a/plugins/ilert/api-report.md +++ b/plugins/ilert/api-report.md @@ -539,7 +539,6 @@ const ilertPlugin: BackstagePlugin< { root: RouteRef; }, - {}, {} >; export { ilertPlugin }; diff --git a/plugins/jenkins/api-report.md b/plugins/jenkins/api-report.md index 0782f0abd2..611a56cd5f 100644 --- a/plugins/jenkins/api-report.md +++ b/plugins/jenkins/api-report.md @@ -99,7 +99,6 @@ const jenkinsPlugin: BackstagePlugin< { entityContent: RouteRef; }, - {}, {} >; export { jenkinsPlugin }; diff --git a/plugins/kafka/api-report.md b/plugins/kafka/api-report.md index 990a4da295..ba0c9a3820 100644 --- a/plugins/kafka/api-report.md +++ b/plugins/kafka/api-report.md @@ -28,7 +28,6 @@ const kafkaPlugin: BackstagePlugin< { entityContent: RouteRef; }, - {}, {} >; export { kafkaPlugin }; diff --git a/plugins/kubernetes/api-report.md b/plugins/kubernetes/api-report.md index 77ec8dd19c..d1c1748758 100644 --- a/plugins/kubernetes/api-report.md +++ b/plugins/kubernetes/api-report.md @@ -513,7 +513,6 @@ const kubernetesPlugin: BackstagePlugin< { entityContent: RouteRef; }, - {}, {} >; export { kubernetesPlugin }; diff --git a/plugins/lighthouse/api-report.md b/plugins/lighthouse/api-report.md index 9794fe1728..40a4ff514f 100644 --- a/plugins/lighthouse/api-report.md +++ b/plugins/lighthouse/api-report.md @@ -49,7 +49,6 @@ const lighthousePlugin: BackstagePlugin< root: RouteRef; entityContent: RouteRef; }, - {}, {} >; export { lighthousePlugin }; diff --git a/plugins/linguist/api-report.md b/plugins/linguist/api-report.md index 5182ce12f6..71e2460088 100644 --- a/plugins/linguist/api-report.md +++ b/plugins/linguist/api-report.md @@ -16,7 +16,7 @@ export const EntityLinguistCard: () => JSX_2.Element; export const isLinguistAvailable: (entity: Entity) => boolean; // @public (undocumented) -export const linguistPlugin: BackstagePlugin<{}, {}, {}>; +export const linguistPlugin: BackstagePlugin<{}, {}>; // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/newrelic-dashboard/api-report.md b/plugins/newrelic-dashboard/api-report.md index 2e9b11a88e..ce7b8d5b7e 100644 --- a/plugins/newrelic-dashboard/api-report.md +++ b/plugins/newrelic-dashboard/api-report.md @@ -31,7 +31,6 @@ export const newRelicDashboardPlugin: BackstagePlugin< { root: RouteRef; }, - {}, {} >; diff --git a/plugins/newrelic/api-report.md b/plugins/newrelic/api-report.md index 04fd229465..a77b80c862 100644 --- a/plugins/newrelic/api-report.md +++ b/plugins/newrelic/api-report.md @@ -17,7 +17,6 @@ const newRelicPlugin: BackstagePlugin< { root: RouteRef; }, - {}, {} >; export { newRelicPlugin }; diff --git a/plugins/nomad/api-report.md b/plugins/nomad/api-report.md index c2d06b9892..68cc47c33d 100644 --- a/plugins/nomad/api-report.md +++ b/plugins/nomad/api-report.md @@ -28,7 +28,6 @@ export const nomadPlugin: BackstagePlugin< root: RouteRef; entityContent: RouteRef; }, - {}, {} >; diff --git a/plugins/octopus-deploy/api-report.md b/plugins/octopus-deploy/api-report.md index 713d99aa8f..3d65e40c64 100644 --- a/plugins/octopus-deploy/api-report.md +++ b/plugins/octopus-deploy/api-report.md @@ -55,7 +55,7 @@ export type OctopusDeployment = { }; // @public (undocumented) -export const octopusDeployPlugin: BackstagePlugin<{}, {}, {}>; +export const octopusDeployPlugin: BackstagePlugin<{}, {}>; // @public (undocumented) export type OctopusEnvironment = { diff --git a/plugins/opencost/api-report.md b/plugins/opencost/api-report.md index 079f394618..996bcea6ac 100644 --- a/plugins/opencost/api-report.md +++ b/plugins/opencost/api-report.md @@ -17,7 +17,6 @@ export const openCostPlugin: BackstagePlugin< { root: RouteRef; }, - {}, {} >; ``` diff --git a/plugins/org/api-report.md b/plugins/org/api-report.md index d85df7125c..922b25b610 100644 --- a/plugins/org/api-report.md +++ b/plugins/org/api-report.md @@ -69,8 +69,7 @@ const orgPlugin: BackstagePlugin< {}, { catalogIndex: ExternalRouteRef; - }, - {} + } >; export { orgPlugin }; export { orgPlugin as plugin }; diff --git a/plugins/pagerduty/api-report.md b/plugins/pagerduty/api-report.md index 24c2e103cf..db73259dd5 100644 --- a/plugins/pagerduty/api-report.md +++ b/plugins/pagerduty/api-report.md @@ -177,7 +177,7 @@ export type PagerDutyOnCallsResponse = { }; // @public (undocumented) -const pagerDutyPlugin: BackstagePlugin<{}, {}, {}>; +const pagerDutyPlugin: BackstagePlugin<{}, {}>; export { pagerDutyPlugin }; export { pagerDutyPlugin as plugin }; diff --git a/plugins/periskop/api-report.md b/plugins/periskop/api-report.md index 578fb1dc49..607cbbb4d0 100644 --- a/plugins/periskop/api-report.md +++ b/plugins/periskop/api-report.md @@ -120,7 +120,7 @@ export class PeriskopClient implements PeriskopApi { } // @public (undocumented) -export const periskopPlugin: BackstagePlugin<{}, {}, {}>; +export const periskopPlugin: BackstagePlugin<{}, {}>; // @public (undocumented) export interface RequestHeaders { diff --git a/plugins/playlist/api-report.md b/plugins/playlist/api-report.md index cf0ebe8a37..be7605d1e6 100644 --- a/plugins/playlist/api-report.md +++ b/plugins/playlist/api-report.md @@ -101,7 +101,6 @@ export const playlistPlugin: BackstagePlugin< { root: RouteRef; }, - {}, {} >; ``` diff --git a/plugins/puppetdb/api-report.md b/plugins/puppetdb/api-report.md index c7d1d0ff0e..890980591f 100644 --- a/plugins/puppetdb/api-report.md +++ b/plugins/puppetdb/api-report.md @@ -20,7 +20,7 @@ export const isPuppetDbAvailable: (entity: Entity) => boolean; export const PuppetDbPage: () => JSX_2.Element; // @public -const puppetdbPlugin: BackstagePlugin<{}, {}, {}>; +const puppetdbPlugin: BackstagePlugin<{}, {}>; export { puppetdbPlugin as plugin }; export { puppetdbPlugin }; diff --git a/plugins/rollbar/api-report.md b/plugins/rollbar/api-report.md index 45c672e7bb..c59475466f 100644 --- a/plugins/rollbar/api-report.md +++ b/plugins/rollbar/api-report.md @@ -196,7 +196,6 @@ const rollbarPlugin: BackstagePlugin< { entityContent: RouteRef; }, - {}, {} >; export { rollbarPlugin as plugin }; diff --git a/plugins/scaffolder/api-report.md b/plugins/scaffolder/api-report.md index a776628da5..ddda40d95f 100644 --- a/plugins/scaffolder/api-report.md +++ b/plugins/scaffolder/api-report.md @@ -561,8 +561,7 @@ export const scaffolderPlugin: BackstagePlugin< }, true >; - }, - {} + } >; // @public @deprecated (undocumented) diff --git a/plugins/search/api-report.md b/plugins/search/api-report.md index 616b63bd31..64f596ab11 100644 --- a/plugins/search/api-report.md +++ b/plugins/search/api-report.md @@ -71,7 +71,6 @@ const searchPlugin: BackstagePlugin< { root: RouteRef; }, - {}, {} >; export { searchPlugin as plugin }; diff --git a/plugins/sentry/api-report.md b/plugins/sentry/api-report.md index 43a5caa0bd..dc5fb69556 100644 --- a/plugins/sentry/api-report.md +++ b/plugins/sentry/api-report.md @@ -138,7 +138,6 @@ const sentryPlugin: BackstagePlugin< { root: RouteRef; }, - {}, {} >; export { sentryPlugin as plugin }; diff --git a/plugins/shortcuts/api-report.md b/plugins/shortcuts/api-report.md index ae8225d5b5..64d9d15156 100644 --- a/plugins/shortcuts/api-report.md +++ b/plugins/shortcuts/api-report.md @@ -58,7 +58,7 @@ export const Shortcuts: (props: ShortcutsProps) => JSX_2.Element; export const shortcutsApiRef: ApiRef; // @public (undocumented) -export const shortcutsPlugin: BackstagePlugin<{}, {}, {}>; +export const shortcutsPlugin: BackstagePlugin<{}, {}>; // @public export interface ShortcutsProps { diff --git a/plugins/sonarqube/api-report.md b/plugins/sonarqube/api-report.md index 72f2eb1c09..32894b6eeb 100644 --- a/plugins/sonarqube/api-report.md +++ b/plugins/sonarqube/api-report.md @@ -71,5 +71,5 @@ export type SonarQubeContentPageProps = { }; // @public (undocumented) -export const sonarQubePlugin: BackstagePlugin<{}, {}, {}>; +export const sonarQubePlugin: BackstagePlugin<{}, {}>; ``` diff --git a/plugins/splunk-on-call/api-report.md b/plugins/splunk-on-call/api-report.md index 4c054e8a1a..d80ee6f874 100644 --- a/plugins/splunk-on-call/api-report.md +++ b/plugins/splunk-on-call/api-report.md @@ -240,7 +240,6 @@ const splunkOnCallPlugin: BackstagePlugin< { root: RouteRef; }, - {}, {} >; export { splunkOnCallPlugin as plugin }; diff --git a/plugins/stack-overflow/api-report.md b/plugins/stack-overflow/api-report.md index 4277aaac24..293c2ac226 100644 --- a/plugins/stack-overflow/api-report.md +++ b/plugins/stack-overflow/api-report.md @@ -32,7 +32,7 @@ export const stackOverflowApiRef: ApiRef; export const StackOverflowIcon: () => React_2.JSX.Element; // @public -export const stackOverflowPlugin: BackstagePlugin<{}, {}, {}>; +export const stackOverflowPlugin: BackstagePlugin<{}, {}>; // @public export type StackOverflowQuestion = { diff --git a/plugins/stackstorm/api-report.md b/plugins/stackstorm/api-report.md index f6279be1bd..14f09c3202 100644 --- a/plugins/stackstorm/api-report.md +++ b/plugins/stackstorm/api-report.md @@ -25,7 +25,6 @@ export const stackstormPlugin: BackstagePlugin< { root: RouteRef; }, - {}, {} >; ``` diff --git a/plugins/tech-insights/api-report.md b/plugins/tech-insights/api-report.md index 14fe512ba0..92f66c14b3 100644 --- a/plugins/tech-insights/api-report.md +++ b/plugins/tech-insights/api-report.md @@ -125,7 +125,6 @@ export const techInsightsPlugin: BackstagePlugin< { root: RouteRef; }, - {}, {} >; diff --git a/plugins/tech-radar/api-report.md b/plugins/tech-radar/api-report.md index f55f0ee39e..178fc202cd 100644 --- a/plugins/tech-radar/api-report.md +++ b/plugins/tech-radar/api-report.md @@ -106,7 +106,6 @@ const techRadarPlugin: BackstagePlugin< { root: RouteRef; }, - {}, {} >; export { techRadarPlugin as plugin }; diff --git a/plugins/techdocs-module-addons-contrib/api-report.md b/plugins/techdocs-module-addons-contrib/api-report.md index c242bb02f2..48e6b2bcdc 100644 --- a/plugins/techdocs-module-addons-contrib/api-report.md +++ b/plugins/techdocs-module-addons-contrib/api-report.md @@ -34,7 +34,7 @@ export type ReportIssueTemplateBuilder = (options: { }) => ReportIssueTemplate; // @public -export const techdocsModuleAddonsContribPlugin: BackstagePlugin<{}, {}, {}>; +export const techdocsModuleAddonsContribPlugin: BackstagePlugin<{}, {}>; // @public export const TextSize: () => JSX.Element | null; diff --git a/plugins/techdocs/api-report.md b/plugins/techdocs/api-report.md index 3207a16f87..761de92f77 100644 --- a/plugins/techdocs/api-report.md +++ b/plugins/techdocs/api-report.md @@ -318,7 +318,6 @@ const techdocsPlugin: BackstagePlugin< }>; entityContent: RouteRef; }, - {}, {} >; export { techdocsPlugin as plugin }; diff --git a/plugins/todo/api-report.md b/plugins/todo/api-report.md index ae4c4f3645..215d1730bc 100644 --- a/plugins/todo/api-report.md +++ b/plugins/todo/api-report.md @@ -85,7 +85,6 @@ export const todoPlugin: BackstagePlugin< { entityContent: RouteRef; }, - {}, {} >; ``` diff --git a/plugins/user-settings/api-report.md b/plugins/user-settings/api-report.md index cdb576c45c..b92677f8ce 100644 --- a/plugins/user-settings/api-report.md +++ b/plugins/user-settings/api-report.md @@ -112,7 +112,6 @@ const userSettingsPlugin: BackstagePlugin< { settingsPage: RouteRef; }, - {}, {} >; export { userSettingsPlugin as plugin }; diff --git a/plugins/vault/api-report.md b/plugins/vault/api-report.md index da13e2092d..59bcb1c527 100644 --- a/plugins/vault/api-report.md +++ b/plugins/vault/api-report.md @@ -33,7 +33,7 @@ export interface VaultApi { export const vaultApiRef: ApiRef; // @public -export const vaultPlugin: BackstagePlugin<{}, {}, {}>; +export const vaultPlugin: BackstagePlugin<{}, {}>; // @public export type VaultSecret = { diff --git a/plugins/xcmetrics/api-report.md b/plugins/xcmetrics/api-report.md index 4cbac0683c..94a2d4afcd 100644 --- a/plugins/xcmetrics/api-report.md +++ b/plugins/xcmetrics/api-report.md @@ -17,7 +17,6 @@ export const xcmetricsPlugin: BackstagePlugin< { root: RouteRef; }, - {}, {} >; ``` From aaaa16211e202598fb457746e4ebf56cc28e4165 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 25 Sep 2023 09:54:09 +0200 Subject: [PATCH 039/110] docs: remove plugin customization docs Signed-off-by: Patrik Oldsberg --- docs/plugins/customization.md | 68 ----------------------------------- microsite/sidebars.json | 1 - 2 files changed, 69 deletions(-) delete mode 100644 docs/plugins/customization.md diff --git a/docs/plugins/customization.md b/docs/plugins/customization.md deleted file mode 100644 index 44ca5147ea..0000000000 --- a/docs/plugins/customization.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -id: customization -title: Customization (Experimental) -description: Documentation on adding a customization logic to the plugin ---- - -## Overview - -The Backstage core logic provides a possibility to make the component customizable in such a way that the application -developer can redefine the labels, icons, elements or even completely replace the component. It's up to each plugin -to decide what can be customized. - -## For a plugin developer - -When you are creating your plugin, you have a possibility to use a metadata field and define there all -customizable elements. For example - -```typescript jsx -const plugin = createPlugin({ - id: 'my-plugin', - __experimentalConfigure( - options?: CatalogInputPluginOptions, - ): CatalogPluginOptions { - const defaultOptions = { - createButtonTitle: 'Create', - }; - return { ...defaultOptions, ...options }; - }, -}); -``` - -And the rendering part of the exposed component can retrieve that metadata as: - -```typescript jsx -export type CatalogPluginOptions = { - createButtonTitle: string; -}; - -export type CatalogInputPluginOptions = { - createButtonTitle: string; -}; - -export const useCatalogPluginOptions = () => - usePluginOptions(); - -export function DefaultMyPluginWelcomePage() { - const { createButtonTitle } = useCatalogPluginOptions(); - - return ( -
- -
- ); -} -``` - -## For an application developer using the plugin - -The way to reconfigure the default values provided by the plugin you can do it via reconfigure method, defined on the -plugin. Example: - -```typescript jsx -import { myPlugin } from '@backstage/my-plugin'; - -myPlugin.__experimentalReconfigure({ - createButtonTitle: 'New', -}); -``` diff --git a/microsite/sidebars.json b/microsite/sidebars.json index 0f4aef1373..bc394982ca 100644 --- a/microsite/sidebars.json +++ b/microsite/sidebars.json @@ -243,7 +243,6 @@ "plugins/integrating-plugin-into-software-catalog", "plugins/integrating-search-into-plugins", "plugins/composability", - "plugins/customization", "plugins/internationalization", "plugins/analytics", "plugins/feature-flags", From 42ccfeb4d052bea45b446a50c77a5eda3db78df4 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Mon, 25 Sep 2023 10:18:59 +0200 Subject: [PATCH 040/110] update api report Signed-off-by: Johan Haals --- plugins/tech-radar/alpha-api-report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/tech-radar/alpha-api-report.md b/plugins/tech-radar/alpha-api-report.md index 23c5d5d353..c54f692982 100644 --- a/plugins/tech-radar/alpha-api-report.md +++ b/plugins/tech-radar/alpha-api-report.md @@ -16,8 +16,8 @@ export const TechRadarPage: Extension<{ width: number; title: string; path: string; + subtitle: string; pageTitle: string; - subTitle: string; }>; // (No @packageDocumentation comment for this package) From 8ff2e84ddbe12be797b2af223173edcc65a73599 Mon Sep 17 00:00:00 2001 From: blam Date: Fri, 22 Sep 2023 16:10:59 +0200 Subject: [PATCH 041/110] feat: move over these metrics to open telemetry too Signed-off-by: blam --- .../catalog-backend/src/database/metrics.ts | 62 ++++++++++++++++--- 1 file changed, 55 insertions(+), 7 deletions(-) diff --git a/plugins/catalog-backend/src/database/metrics.ts b/plugins/catalog-backend/src/database/metrics.ts index b6c4e248dc..58ad91f93b 100644 --- a/plugins/catalog-backend/src/database/metrics.ts +++ b/plugins/catalog-backend/src/database/metrics.ts @@ -17,11 +17,14 @@ import { Knex } from 'knex'; import { createGaugeMetric } from '../util/metrics'; import { DbRefreshStateRow, DbRelationsRow, DbLocationsRow } from './tables'; +import { metrics } from '@opentelemetry/api'; export function initDatabaseMetrics(knex: Knex) { + const seenProm = new Set(); const seen = new Set(); + const meter = metrics.getMeter('default'); return { - entities_count: createGaugeMetric({ + entities_count_prom: createGaugeMetric({ name: 'catalog_entities_count', help: 'Total amount of entities in the catalog', labelNames: ['kind'], @@ -34,20 +37,20 @@ export function initDatabaseMetrics(knex: Knex) { .reduce((acc, e) => acc.set(e, (acc.get(e) || 0) + 1), new Map()); results.forEach((value, key) => { - seen.add(key); + seenProm.add(key); this.set({ kind: key }, value); }); - // Set all the entities that were not seen to 0 and delete them from the seen set. - seen.forEach(key => { + // Set all the entities that were not seenProm to 0 and delete them from the seenProm set. + seenProm.forEach(key => { if (!results.has(key)) { this.set({ kind: key }, 0); - seen.delete(key); + seenProm.delete(key); } }); }, }), - registered_locations: createGaugeMetric({ + registered_locations_prom: createGaugeMetric({ name: 'catalog_registered_locations_count', help: 'Total amount of registered locations in the catalog', async collect() { @@ -57,7 +60,7 @@ export function initDatabaseMetrics(knex: Knex) { this.set(Number(total[0].count)); }, }), - relations: createGaugeMetric({ + relations_prom: createGaugeMetric({ name: 'catalog_relations_count', help: 'Total amount of relations between entities', async collect() { @@ -67,5 +70,50 @@ export function initDatabaseMetrics(knex: Knex) { this.set(Number(total[0].count)); }, }), + entities_count: meter + .createObservableGauge('catalog_entities_count', { + description: 'Total amount of entities in the catalog', + }) + .addCallback(async gauge => { + const result = await knex('refresh_state').select( + 'entity_ref', + ); + const results = result + .map(row => row.entity_ref.split(':')[0]) + .reduce((acc, e) => acc.set(e, (acc.get(e) || 0) + 1), new Map()); + + results.forEach((value, key) => { + seen.add(key); + gauge.observe(value, { kind: key }); + }); + + // Set all the entities that were not seen to 0 and delete them from the seen set. + seen.forEach(key => { + if (!results.has(key)) { + gauge.observe(0, { kind: key }); + seen.delete(key); + } + }); + }), + registered_locations: meter + .createObservableGauge('catalog_registered_locations_count', { + description: 'Total amount of registered locations in the catalog', + }) + .addCallback(async gauge => { + const total = await knex('locations').count({ + count: '*', + }); + gauge.observe(Number(total[0].count)); + }), + relations: meter + .createObservableGauge('catalog_relations_count', { + description: 'Total amount of relations between entities', + }) + .addCallback(async gauge => { + const total = await knex('relations').count({ + count: '*', + }); + gauge.observe(Number(total[0].count)); + }), }; } From 8770d122564a700913b7a8738f9a185a0d48b6b8 Mon Sep 17 00:00:00 2001 From: blam Date: Fri, 22 Sep 2023 16:20:13 +0200 Subject: [PATCH 042/110] chore: added deprecated notice Signed-off-by: blam --- plugins/catalog-backend/src/database/metrics.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/catalog-backend/src/database/metrics.ts b/plugins/catalog-backend/src/database/metrics.ts index 58ad91f93b..55bfa66b86 100644 --- a/plugins/catalog-backend/src/database/metrics.ts +++ b/plugins/catalog-backend/src/database/metrics.ts @@ -26,7 +26,7 @@ export function initDatabaseMetrics(knex: Knex) { return { entities_count_prom: createGaugeMetric({ name: 'catalog_entities_count', - help: 'Total amount of entities in the catalog', + help: 'Total amount of entities in the catalog. DEPRECATED: Please use opentelemetry metrics instead.', labelNames: ['kind'], async collect() { const result = await knex('refresh_state').select( @@ -52,7 +52,7 @@ export function initDatabaseMetrics(knex: Knex) { }), registered_locations_prom: createGaugeMetric({ name: 'catalog_registered_locations_count', - help: 'Total amount of registered locations in the catalog', + help: 'Total amount of registered locations in the catalog. DEPRECATED: Please use opentelemetry metrics instead.', async collect() { const total = await knex('locations').count({ count: '*', @@ -62,7 +62,7 @@ export function initDatabaseMetrics(knex: Knex) { }), relations_prom: createGaugeMetric({ name: 'catalog_relations_count', - help: 'Total amount of relations between entities', + help: 'Total amount of relations between entities. DEPRECATED: Please use opentelemetry metrics instead.', async collect() { const total = await knex('relations').count({ count: '*', From 78af9433c8d1a31d4e37e80c96c884564e6261a4 Mon Sep 17 00:00:00 2001 From: blam Date: Fri, 22 Sep 2023 16:21:07 +0200 Subject: [PATCH 043/110] feat: added changeset Signed-off-by: blam --- .changeset/spotty-badgers-wash.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/spotty-badgers-wash.md diff --git a/.changeset/spotty-badgers-wash.md b/.changeset/spotty-badgers-wash.md new file mode 100644 index 0000000000..1ce9c66aee --- /dev/null +++ b/.changeset/spotty-badgers-wash.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': minor +--- + +Instrumenting some missing metrics with `OpenTelemetry` From 54299c496efc61acf78e2bedf4469219e300c572 Mon Sep 17 00:00:00 2001 From: blam Date: Fri, 22 Sep 2023 16:25:09 +0200 Subject: [PATCH 044/110] chore: fixing parsing Signed-off-by: blam --- plugins/catalog-backend/src/database/metrics.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/catalog-backend/src/database/metrics.ts b/plugins/catalog-backend/src/database/metrics.ts index 55bfa66b86..8eb307ea46 100644 --- a/plugins/catalog-backend/src/database/metrics.ts +++ b/plugins/catalog-backend/src/database/metrics.ts @@ -18,6 +18,7 @@ import { Knex } from 'knex'; import { createGaugeMetric } from '../util/metrics'; import { DbRefreshStateRow, DbRelationsRow, DbLocationsRow } from './tables'; import { metrics } from '@opentelemetry/api'; +import { parseEntityRef } from '@backstage/catalog-model'; export function initDatabaseMetrics(knex: Knex) { const seenProm = new Set(); @@ -79,7 +80,7 @@ export function initDatabaseMetrics(knex: Knex) { 'entity_ref', ); const results = result - .map(row => row.entity_ref.split(':')[0]) + .map(row => parseEntityRef(row.entity_ref).kind) .reduce((acc, e) => acc.set(e, (acc.get(e) || 0) + 1), new Map()); results.forEach((value, key) => { From d1b637d0054cf11a2cdf155553a945b41ba62719 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 25 Sep 2023 11:25:46 +0200 Subject: [PATCH 045/110] user-settings: fix theme icon colors Signed-off-by: Patrik Oldsberg --- .changeset/pretty-apes-sneeze.md | 5 +++++ .../src/components/General/UserSettingsThemeToggle.tsx | 8 ++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 .changeset/pretty-apes-sneeze.md diff --git a/.changeset/pretty-apes-sneeze.md b/.changeset/pretty-apes-sneeze.md new file mode 100644 index 0000000000..a1008dc951 --- /dev/null +++ b/.changeset/pretty-apes-sneeze.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-user-settings': patch +--- + +Fixed a bug where the theme icons would not be colored according to their active state. diff --git a/plugins/user-settings/src/components/General/UserSettingsThemeToggle.tsx b/plugins/user-settings/src/components/General/UserSettingsThemeToggle.tsx index 7279fcb96a..ca57de3a78 100644 --- a/plugins/user-settings/src/components/General/UserSettingsThemeToggle.tsx +++ b/plugins/user-settings/src/components/General/UserSettingsThemeToggle.tsx @@ -141,8 +141,8 @@ export const UserSettingsThemeToggle = () => { onChange={handleSetTheme} > {themeIds.map(theme => { - const themeIcon = themeIds.find(it => it.id === theme.id)?.icon; const themeId = theme.id; + const themeIcon = theme.icon; const themeTitle = theme.title || (themeId === 'light' || themeId === 'dark' @@ -156,7 +156,11 @@ export const UserSettingsThemeToggle = () => { > <> {themeTitle}  - + ); From 5d32a58b5a13b0dbf6da5401cb1005554d1b6be3 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 25 Sep 2023 12:10:46 +0200 Subject: [PATCH 046/110] auth-backend-module-github-provider: enable persisted scopes Signed-off-by: Patrik Oldsberg --- .changeset/nice-dancers-explain.md | 5 +++++ .../auth-backend-module-github-provider/src/authenticator.ts | 1 + 2 files changed, 6 insertions(+) create mode 100644 .changeset/nice-dancers-explain.md diff --git a/.changeset/nice-dancers-explain.md b/.changeset/nice-dancers-explain.md new file mode 100644 index 0000000000..5e54a66c05 --- /dev/null +++ b/.changeset/nice-dancers-explain.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend-module-github-provider': patch +--- + +Fixed a bug where the GitHub authenticator did not properly persist granted OAuth scopes. diff --git a/plugins/auth-backend-module-github-provider/src/authenticator.ts b/plugins/auth-backend-module-github-provider/src/authenticator.ts index f59ac3d727..4a9710d114 100644 --- a/plugins/auth-backend-module-github-provider/src/authenticator.ts +++ b/plugins/auth-backend-module-github-provider/src/authenticator.ts @@ -28,6 +28,7 @@ const ACCESS_TOKEN_PREFIX = 'access-token.'; export const githubAuthenticator = createOAuthAuthenticator({ defaultProfileTransform: PassportOAuthAuthenticatorHelper.defaultProfileTransform, + shouldPersistScopes: true, initialize({ callbackUrl, config }) { const clientId = config.getString('clientId'); const clientSecret = config.getString('clientSecret'); From 18f17569084c482fc44b8d1e79959d37fa6a7576 Mon Sep 17 00:00:00 2001 From: npiyush97 Date: Mon, 25 Sep 2023 16:10:53 +0530 Subject: [PATCH 047/110] added aria label for better a11y score Signed-off-by: npiyush97 --- .changeset/wet-olives-wave.md | 5 +++++ plugins/api-docs/src/components/ApisCards/presets.tsx | 8 ++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 .changeset/wet-olives-wave.md diff --git a/.changeset/wet-olives-wave.md b/.changeset/wet-olives-wave.md new file mode 100644 index 0000000000..5b35e0ad90 --- /dev/null +++ b/.changeset/wet-olives-wave.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-api-docs': patch +--- + +added aria-label on api definition button for better a11y. diff --git a/plugins/api-docs/src/components/ApisCards/presets.tsx b/plugins/api-docs/src/components/ApisCards/presets.tsx index b1ef39c113..38f75ecf95 100644 --- a/plugins/api-docs/src/components/ApisCards/presets.tsx +++ b/plugins/api-docs/src/components/ApisCards/presets.tsx @@ -33,10 +33,14 @@ export function createSpecApiTypeColumn(): TableColumn { const ApiDefinitionButton = ({ apiEntity }: { apiEntity: ApiEntity }) => { const [dialogOpen, setDialogOpen] = useState(false); - + // eslint-disable-next-line no-console + console.log('this is the one'); return ( <> - setDialogOpen(!dialogOpen)}> + setDialogOpen(!dialogOpen)} + > Date: Mon, 25 Sep 2023 11:53:14 +0100 Subject: [PATCH 048/110] Increase max allowed length of fact schema's filter Signed-off-by: Brian Fletcher --- .changeset/nice-clocks-smash.md | 5 +++ ...45017_increase_filter_fact_schemas_size.js | 37 +++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 .changeset/nice-clocks-smash.md create mode 100644 plugins/tech-insights-backend/migrations/20230925145017_increase_filter_fact_schemas_size.js diff --git a/.changeset/nice-clocks-smash.md b/.changeset/nice-clocks-smash.md new file mode 100644 index 0000000000..8a289370e5 --- /dev/null +++ b/.changeset/nice-clocks-smash.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-tech-insights-backend': patch +--- + +Increase the maximum allowed length of an entity filter for tech insights fact schemas. diff --git a/plugins/tech-insights-backend/migrations/20230925145017_increase_filter_fact_schemas_size.js b/plugins/tech-insights-backend/migrations/20230925145017_increase_filter_fact_schemas_size.js new file mode 100644 index 0000000000..848fb25777 --- /dev/null +++ b/plugins/tech-insights-backend/migrations/20230925145017_increase_filter_fact_schemas_size.js @@ -0,0 +1,37 @@ +/* + * 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. + */ + +const factSchemasTable = 'fact_schemas'; + +/** + * @param { import("knex").Knex } knex + * @returns { Promise } + */ +exports.up = async function up(knex) { + await knex.schema.alterTable(factSchemasTable, table => { + table.text('entityFilter').alter(); + }); +}; + +/** + * @param { import("knex").Knex } knex + * @returns { Promise } + */ +exports.down = async function down() { + await knex.schema.alterTable(factSchemasTable, table => { + table.string('entityFilter').alter(); + }); +}; From 199f54def40350bc7a1b44cbdb37221188c8edcd Mon Sep 17 00:00:00 2001 From: PIYUSH NEGI <43876655+npiyush97@users.noreply.github.com> Date: Mon, 25 Sep 2023 16:49:24 +0530 Subject: [PATCH 049/110] Update presets.tsx Signed-off-by: PIYUSH NEGI <43876655+npiyush97@users.noreply.github.com> --- plugins/api-docs/src/components/ApisCards/presets.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugins/api-docs/src/components/ApisCards/presets.tsx b/plugins/api-docs/src/components/ApisCards/presets.tsx index 38f75ecf95..d45cf5ea64 100644 --- a/plugins/api-docs/src/components/ApisCards/presets.tsx +++ b/plugins/api-docs/src/components/ApisCards/presets.tsx @@ -33,8 +33,6 @@ export function createSpecApiTypeColumn(): TableColumn { const ApiDefinitionButton = ({ apiEntity }: { apiEntity: ApiEntity }) => { const [dialogOpen, setDialogOpen] = useState(false); - // eslint-disable-next-line no-console - console.log('this is the one'); return ( <> Date: Mon, 25 Sep 2023 14:02:15 +0200 Subject: [PATCH 050/110] auth-node: fix for persisted scopes not being restored on sign-in Signed-off-by: Patrik Oldsberg --- .changeset/plenty-llamas-double.md | 5 +++++ .../src/oauth/createOAuthRouteHandlers.test.ts | 14 +++++++++----- .../src/oauth/createOAuthRouteHandlers.ts | 2 +- 3 files changed, 15 insertions(+), 6 deletions(-) create mode 100644 .changeset/plenty-llamas-double.md diff --git a/.changeset/plenty-llamas-double.md b/.changeset/plenty-llamas-double.md new file mode 100644 index 0000000000..b2691a2f17 --- /dev/null +++ b/.changeset/plenty-llamas-double.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-node': patch +--- + +Fix for persisted scopes not being properly restored on sign-in. diff --git a/plugins/auth-node/src/oauth/createOAuthRouteHandlers.test.ts b/plugins/auth-node/src/oauth/createOAuthRouteHandlers.test.ts index 2573d95ea1..7da5519655 100644 --- a/plugins/auth-node/src/oauth/createOAuthRouteHandlers.test.ts +++ b/plugins/auth-node/src/oauth/createOAuthRouteHandlers.test.ts @@ -297,7 +297,7 @@ describe('createOAuthRouteHandlers', () => { state: encodeOAuthState({ env: 'development', nonce: '123', - scope: 'my-scope', + scope: 'my-scope my-other-scope', } as OAuthState), }); @@ -310,7 +310,7 @@ describe('createOAuthRouteHandlers', () => { accessToken: 'access-token', expiresInSeconds: 3, idToken: 'id-token', - scope: 'my-scope', + scope: 'my-scope my-other-scope', }, backstageIdentity: { identity: { @@ -324,7 +324,9 @@ describe('createOAuthRouteHandlers', () => { }); expect(getRefreshTokenCookie(agent).value).toBe('refresh-token'); - expect(getGrantedScopesCookie(agent).value).toBe('my-scope'); + expect(getGrantedScopesCookie(agent).value).toBe( + 'my-scope%20my-other-scope', + ); }); it('should redirect with persisted scope', async () => { @@ -357,7 +359,7 @@ describe('createOAuthRouteHandlers', () => { state: encodeOAuthState({ env: 'development', nonce: '123', - scope: 'my-scope', + scope: 'my-scope my-other-scope', flow: 'redirect', redirectUrl: 'https://127.0.0.1:3000/redirect', } as OAuthState), @@ -367,7 +369,9 @@ describe('createOAuthRouteHandlers', () => { expect(res.get('Location')).toBe('https://127.0.0.1:3000/redirect'); expect(getRefreshTokenCookie(agent).value).toBe('refresh-token'); - expect(getGrantedScopesCookie(agent).value).toBe('my-scope'); + expect(getGrantedScopesCookie(agent).value).toBe( + 'my-scope%20my-other-scope', + ); }); it('should require a valid origin', async () => { diff --git a/plugins/auth-node/src/oauth/createOAuthRouteHandlers.ts b/plugins/auth-node/src/oauth/createOAuthRouteHandlers.ts index 011b3fc0f0..a455837035 100644 --- a/plugins/auth-node/src/oauth/createOAuthRouteHandlers.ts +++ b/plugins/auth-node/src/oauth/createOAuthRouteHandlers.ts @@ -214,7 +214,7 @@ export function createOAuthRouteHandlers( // the provider does not return granted scopes on refresh or if they are normalized. if (authenticator.shouldPersistScopes && state.scope) { cookieManager.setGrantedScopes(res, state.scope, appOrigin); - result.session.scope = state.scope; + response.providerInfo.scope = state.scope; } if (result.session.refreshToken) { From e77ecb6e9d8b5290a9e67266892458db769ab82c Mon Sep 17 00:00:00 2001 From: PIYUSH NEGI <43876655+npiyush97@users.noreply.github.com> Date: Mon, 25 Sep 2023 17:55:34 +0530 Subject: [PATCH 051/110] Update plugins/api-docs/src/components/ApisCards/presets.tsx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Signed-off-by: PIYUSH NEGI <43876655+npiyush97@users.noreply.github.com> --- plugins/api-docs/src/components/ApisCards/presets.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/api-docs/src/components/ApisCards/presets.tsx b/plugins/api-docs/src/components/ApisCards/presets.tsx index d45cf5ea64..050944b239 100644 --- a/plugins/api-docs/src/components/ApisCards/presets.tsx +++ b/plugins/api-docs/src/components/ApisCards/presets.tsx @@ -36,7 +36,7 @@ const ApiDefinitionButton = ({ apiEntity }: { apiEntity: ApiEntity }) => { return ( <> setDialogOpen(!dialogOpen)} > From f5b41b27a920b9ad134a1f177bd155bcddab3e97 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 25 Sep 2023 10:46:48 +0200 Subject: [PATCH 052/110] initial e2e-test-utils package Signed-off-by: Patrik Oldsberg --- .changeset/thirty-coins-sneeze.md | 5 ++++ packages/e2e-test-utils/.eslintrc.js | 1 + packages/e2e-test-utils/README.md | 12 +++++++++ packages/e2e-test-utils/package.json | 31 +++++++++++++++++++++++ packages/e2e-test-utils/src/index.ts | 16 ++++++++++++ packages/e2e-test-utils/src/setupTests.ts | 16 ++++++++++++ yarn.lock | 8 ++++++ 7 files changed, 89 insertions(+) create mode 100644 .changeset/thirty-coins-sneeze.md create mode 100644 packages/e2e-test-utils/.eslintrc.js create mode 100644 packages/e2e-test-utils/README.md create mode 100644 packages/e2e-test-utils/package.json create mode 100644 packages/e2e-test-utils/src/index.ts create mode 100644 packages/e2e-test-utils/src/setupTests.ts diff --git a/.changeset/thirty-coins-sneeze.md b/.changeset/thirty-coins-sneeze.md new file mode 100644 index 0000000000..58a93065b8 --- /dev/null +++ b/.changeset/thirty-coins-sneeze.md @@ -0,0 +1,5 @@ +--- +'@backstage/e2e-test-utils': minor +--- + +Initial release. diff --git a/packages/e2e-test-utils/.eslintrc.js b/packages/e2e-test-utils/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/packages/e2e-test-utils/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/packages/e2e-test-utils/README.md b/packages/e2e-test-utils/README.md new file mode 100644 index 0000000000..e3e0334020 --- /dev/null +++ b/packages/e2e-test-utils/README.md @@ -0,0 +1,12 @@ +# @backstage/e2e-test-utils + +_This package was created through the Backstage CLI_. + +## Installation + +Install the package via Yarn: + +```sh +cd # if within a monorepo +yarn add @backstage/e2e-test-utils +``` diff --git a/packages/e2e-test-utils/package.json b/packages/e2e-test-utils/package.json new file mode 100644 index 0000000000..7f6b180f43 --- /dev/null +++ b/packages/e2e-test-utils/package.json @@ -0,0 +1,31 @@ +{ + "name": "@backstage/e2e-test-utils", + "description": "Shared end-to-end test utilities Backstage", + "version": "0.0.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": "node-library" + }, + "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" + }, + "devDependencies": { + "@backstage/cli": "workspace:^" + }, + "files": [ + "dist" + ] +} diff --git a/packages/e2e-test-utils/src/index.ts b/packages/e2e-test-utils/src/index.ts new file mode 100644 index 0000000000..4b9026cde5 --- /dev/null +++ b/packages/e2e-test-utils/src/index.ts @@ -0,0 +1,16 @@ +/* + * 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. + */ +export {}; diff --git a/packages/e2e-test-utils/src/setupTests.ts b/packages/e2e-test-utils/src/setupTests.ts new file mode 100644 index 0000000000..4b9026cde5 --- /dev/null +++ b/packages/e2e-test-utils/src/setupTests.ts @@ -0,0 +1,16 @@ +/* + * 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. + */ +export {}; diff --git a/yarn.lock b/yarn.lock index 0fbf06209b..04a2950f3f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4180,6 +4180,14 @@ __metadata: languageName: unknown linkType: soft +"@backstage/e2e-test-utils@workspace:packages/e2e-test-utils": + version: 0.0.0-use.local + resolution: "@backstage/e2e-test-utils@workspace:packages/e2e-test-utils" + dependencies: + "@backstage/cli": "workspace:^" + languageName: unknown + linkType: soft + "@backstage/errors@^1.1.5, @backstage/errors@workspace:^, @backstage/errors@workspace:packages/errors": version: 0.0.0-use.local resolution: "@backstage/errors@workspace:packages/errors" From 8d11fed2461d459ea4c5c591dd8205b7fc7fcb60 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 25 Sep 2023 10:55:31 +0200 Subject: [PATCH 053/110] e2e-test-utils: add playwright utilities Signed-off-by: Patrik Oldsberg --- packages/e2e-test-utils/package.json | 27 +++++++++-- .../src/playwright/failOnBrowserErrors.ts | 37 +++++++++++++++ .../src/playwright/generateProjects.ts | 42 +++++++++++++++++ .../e2e-test-utils/src/playwright/index.ts | 18 ++++++++ yarn.lock | 46 +++++++++++++++++-- 5 files changed, 163 insertions(+), 7 deletions(-) create mode 100644 packages/e2e-test-utils/src/playwright/failOnBrowserErrors.ts create mode 100644 packages/e2e-test-utils/src/playwright/generateProjects.ts create mode 100644 packages/e2e-test-utils/src/playwright/index.ts diff --git a/packages/e2e-test-utils/package.json b/packages/e2e-test-utils/package.json index 7f6b180f43..ee18258768 100644 --- a/packages/e2e-test-utils/package.json +++ b/packages/e2e-test-utils/package.json @@ -6,9 +6,21 @@ "types": "src/index.ts", "license": "Apache-2.0", "publishConfig": { - "access": "public", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" + "access": "public" + }, + "exports": { + "./playwright": "./src/playwright/index.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "playwright": [ + "src/playwright/index.ts" + ], + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "node-library" @@ -22,8 +34,15 @@ "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack" }, + "dependencies": { + "@manypkg/get-packages": "^1.1.3", + "@playwright/test": "^1.32.3", + "fs-extra": "^10.1.0" + }, "devDependencies": { - "@backstage/cli": "workspace:^" + "@backstage/cli": "workspace:^", + "@backstage/cli-node": "workspace:^", + "@types/fs-extra": "^9.0.1" }, "files": [ "dist" diff --git a/packages/e2e-test-utils/src/playwright/failOnBrowserErrors.ts b/packages/e2e-test-utils/src/playwright/failOnBrowserErrors.ts new file mode 100644 index 0000000000..af7baa9540 --- /dev/null +++ b/packages/e2e-test-utils/src/playwright/failOnBrowserErrors.ts @@ -0,0 +1,37 @@ +/* + * 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 { test } from '@playwright/test'; + +/** + * Calling this at the top of your test file will ensure that tests fail if the browser + * logs any errors or if there are any uncaught exceptions. + * + * @public + */ +export function failOnBrowserErrors(): void { + test.beforeEach(async ({ page }) => { + page.on('pageerror', error => { + throw new Error(`Uncaught exception on page, ${error}`); + }); + + page.on('console', msg => { + if (msg.type() === 'error') { + throw new Error(`Unexpected console error message "${msg.text()}"`); + } + }); + }); +} diff --git a/packages/e2e-test-utils/src/playwright/generateProjects.ts b/packages/e2e-test-utils/src/playwright/generateProjects.ts new file mode 100644 index 0000000000..b6f3d159c5 --- /dev/null +++ b/packages/e2e-test-utils/src/playwright/generateProjects.ts @@ -0,0 +1,42 @@ +/* + * 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 fs from 'fs-extra'; +import { resolve as resolvePath } from 'path'; +import { PlaywrightTestConfig } from '@playwright/test'; +import { getPackagesSync } from '@manypkg/get-packages'; +import type { BackstagePackage } from '@backstage/cli-node'; + +/** + * Generates a list of playwright projects by scanning the monorepo for packages with an `e2e-tests/` folder. + * + * @public + */ +export function generateProjects(): PlaywrightTestConfig['projects'] { + // TODO(Rugvip): Switch this over to use @backstage/cli-node once released, and support SINCE=origin/main + const { root, packages } = getPackagesSync(process.cwd()); + const e2eTestPackages = [...(root ? [root] : []), ...packages].filter(pkg => { + return fs.pathExistsSync(resolvePath(pkg.dir, 'e2e-tests')); + }) as BackstagePackage[]; + + return e2eTestPackages.map(pkg => ({ + name: pkg.packageJson.name, + testDir: resolvePath(pkg.dir, 'e2e-tests'), + use: { + channel: 'chrome', + }, + })); +} diff --git a/packages/e2e-test-utils/src/playwright/index.ts b/packages/e2e-test-utils/src/playwright/index.ts new file mode 100644 index 0000000000..c5750581d7 --- /dev/null +++ b/packages/e2e-test-utils/src/playwright/index.ts @@ -0,0 +1,18 @@ +/* + * 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. + */ + +export { generateProjects } from './generateProjects'; +export { failOnBrowserErrors } from './failOnBrowserErrors'; diff --git a/yarn.lock b/yarn.lock index 04a2950f3f..c70add6790 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4185,6 +4185,11 @@ __metadata: resolution: "@backstage/e2e-test-utils@workspace:packages/e2e-test-utils" dependencies: "@backstage/cli": "workspace:^" + "@backstage/cli-node": "workspace:^" + "@manypkg/get-packages": ^1.1.3 + "@playwright/test": ^1.32.3 + "@types/fs-extra": ^9.0.1 + fs-extra: ^10.1.0 languageName: unknown linkType: soft @@ -14218,6 +14223,17 @@ __metadata: languageName: node linkType: hard +"@playwright/test@npm:^1.32.3": + version: 1.38.1 + resolution: "@playwright/test@npm:1.38.1" + dependencies: + playwright: 1.38.1 + bin: + playwright: cli.js + checksum: c5ec0b23261fe1ef163b6234f69263bc10e7e5a3fb676c7773ffc70b87459a7ab225f57c03b9de649475771638a04c2e00d9b2739304a4dcf5d3edf20a7a4a82 + languageName: node + linkType: hard + "@pmmmwh/react-refresh-webpack-plugin@npm:^0.5.7": version: 0.5.11 resolution: "@pmmmwh/react-refresh-webpack-plugin@npm:0.5.11" @@ -26752,7 +26768,7 @@ __metadata: languageName: node linkType: hard -"fs-extra@npm:10.1.0, fs-extra@npm:^10.0.0, fs-extra@npm:^10.0.1": +"fs-extra@npm:10.1.0, fs-extra@npm:^10.0.0, fs-extra@npm:^10.0.1, fs-extra@npm:^10.1.0": version: 10.1.0 resolution: "fs-extra@npm:10.1.0" dependencies: @@ -26829,7 +26845,7 @@ __metadata: languageName: node linkType: hard -"fsevents@npm:^2.3.2, fsevents@npm:~2.3.2": +"fsevents@npm:2.3.2, fsevents@npm:^2.3.2, fsevents@npm:~2.3.2": version: 2.3.2 resolution: "fsevents@npm:2.3.2" dependencies: @@ -26839,7 +26855,7 @@ __metadata: languageName: node linkType: hard -"fsevents@patch:fsevents@^2.3.2#~builtin, fsevents@patch:fsevents@~2.3.2#~builtin": +"fsevents@patch:fsevents@2.3.2#~builtin, fsevents@patch:fsevents@^2.3.2#~builtin, fsevents@patch:fsevents@~2.3.2#~builtin": version: 2.3.2 resolution: "fsevents@patch:fsevents@npm%3A2.3.2#~builtin::version=2.3.2&hash=18f3a7" dependencies: @@ -35546,6 +35562,30 @@ __metadata: languageName: node linkType: hard +"playwright-core@npm:1.38.1": + version: 1.38.1 + resolution: "playwright-core@npm:1.38.1" + bin: + playwright-core: cli.js + checksum: 66e83fe040f309b13ad94ba39dea40ac207bfcbbc22de13141af88dbdedd64e1c4e3ce1d0cb070d4efd8050d7e579953ec3681dd8a0acf2c1cc738d9c50e545e + languageName: node + linkType: hard + +"playwright@npm:1.38.1": + version: 1.38.1 + resolution: "playwright@npm:1.38.1" + dependencies: + fsevents: 2.3.2 + playwright-core: 1.38.1 + dependenciesMeta: + fsevents: + optional: true + bin: + playwright: cli.js + checksum: 4e01d4ee52d9ccf75a80d8492829106802590721d56bff7c5957ff1f21eb3c328ee5bc3c1784a59c4b515df1b98d08ef92e4a35a807f454cd00dc481d30fadc2 + languageName: node + linkType: hard + "pluralize@npm:^8.0.0": version: 8.0.0 resolution: "pluralize@npm:8.0.0" From a07764f44accb4be271ad005a08014dd6ab499f0 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 25 Sep 2023 16:37:31 +0200 Subject: [PATCH 054/110] remove cypress MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Johan Haals Signed-off-by: Patrik Oldsberg --- .dockerignore | 1 - .github/CODEOWNERS | 1 - .gitignore | 3 - app-config.yaml | 3 - cypress/.eslintrc.js | 9 - cypress/.npmrc | 2 - cypress/.yarnrc | 5 - cypress/README.md | 34 - cypress/cypress.json | 10 - cypress/e2e-fixture.catalog.info.yaml | 11 - cypress/fixtures/docs/index.md | 3 - cypress/fixtures/docs/sub-page-one.md | 109 -- cypress/fixtures/docs/sub-page-three.md | 121 -- cypress/fixtures/docs/sub-page-two.md | 146 -- cypress/fixtures/mkdocs.yml | 13 - cypress/package.json | 11 - cypress/src/fixtures/.gitkeep | 0 cypress/src/integration/integrations.spec.ts | 82 - .../src/integration/plugins/catalog.spec.ts | 199 -- .../integration/plugins/score-card.spec.ts | 83 - .../src/integration/plugins/techdocs.spec.ts | 259 --- cypress/src/integration/user/login.spec.ts | 31 - cypress/src/integration/user/logout.spec.ts | 35 - cypress/src/plugins/index.ts | 16 - cypress/src/support/commands.ts | 125 -- cypress/src/support/index.ts | 17 - cypress/src/types.d.ts | 86 - cypress/support/commands.ts | 52 - cypress/support/e2e.ts | 35 - cypress/tsconfig.json | 37 - cypress/yarn.lock | 1639 ----------------- packages/app-next/package.json | 12 +- packages/app/cypress.json | 5 - packages/app/cypress/.eslintrc.json | 12 - packages/app/cypress/integration/app.js | 67 - .../components/search/SearchPage.js | 121 -- packages/app/cypress/support/commands.js | 19 - packages/app/cypress/support/index.js | 17 - packages/app/package.json | 12 +- packages/e2e-test-utils/catalog-info.yaml | 10 + .../techdocs-cli-embedded-app/cypress.json | 5 - .../cypress/.eslintrc.json | 12 - .../cypress/integration/app.js | 22 - .../techdocs-cli-embedded-app/package.json | 11 +- packages/techdocs-cli/README.md | 35 - packages/techdocs-cli/cypress.config.js | 30 - packages/techdocs-cli/cypress/.eslintrc.json | 12 - ...eSnapshot - Backstage TechDocs Page #0.png | Bin 67783 -> 0 bytes ... toMatchImageSnapshot - MkDocs Page #0.png | Bin 170963 -> 0 bytes .../cypress/e2e/backstage_serve.cy.js | 58 - .../cypress/e2e/mkdocs_serve.cy.js | 48 - .../cypress/fixtures/example.json | 5 - ...tchImageSnapshot - Backstage Header #0.png | Bin 401484 -> 0 bytes ...pshot - Backstage TechDocs Page #0 (1).png | Bin 330242 -> 0 bytes ...pshot - Backstage TechDocs Page #0 (2).png | Bin 12319 -> 0 bytes ...eSnapshot - Backstage TechDocs Page #0.png | Bin 330242 -> 0 bytes .../techdocs-cli/cypress/support/commands.js | 40 - packages/techdocs-cli/cypress/support/e2e.js | 36 - packages/techdocs-cli/package.json | 3 - scripts/verify-lockfile-duplicates.js | 2 +- yarn.lock | 780 +------- 61 files changed, 72 insertions(+), 4480 deletions(-) delete mode 100644 cypress/.eslintrc.js delete mode 100644 cypress/.npmrc delete mode 100644 cypress/.yarnrc delete mode 100644 cypress/README.md delete mode 100644 cypress/cypress.json delete mode 100644 cypress/e2e-fixture.catalog.info.yaml delete mode 100644 cypress/fixtures/docs/index.md delete mode 100644 cypress/fixtures/docs/sub-page-one.md delete mode 100644 cypress/fixtures/docs/sub-page-three.md delete mode 100644 cypress/fixtures/docs/sub-page-two.md delete mode 100644 cypress/fixtures/mkdocs.yml delete mode 100644 cypress/package.json delete mode 100644 cypress/src/fixtures/.gitkeep delete mode 100644 cypress/src/integration/integrations.spec.ts delete mode 100644 cypress/src/integration/plugins/catalog.spec.ts delete mode 100644 cypress/src/integration/plugins/score-card.spec.ts delete mode 100644 cypress/src/integration/plugins/techdocs.spec.ts delete mode 100644 cypress/src/integration/user/login.spec.ts delete mode 100644 cypress/src/integration/user/logout.spec.ts delete mode 100644 cypress/src/plugins/index.ts delete mode 100644 cypress/src/support/commands.ts delete mode 100644 cypress/src/support/index.ts delete mode 100644 cypress/src/types.d.ts delete mode 100644 cypress/support/commands.ts delete mode 100644 cypress/support/e2e.ts delete mode 100644 cypress/tsconfig.json delete mode 100644 cypress/yarn.lock delete mode 100644 packages/app/cypress.json delete mode 100644 packages/app/cypress/.eslintrc.json delete mode 100644 packages/app/cypress/integration/app.js delete mode 100644 packages/app/cypress/integration/components/search/SearchPage.js delete mode 100644 packages/app/cypress/support/commands.js delete mode 100644 packages/app/cypress/support/index.js create mode 100644 packages/e2e-test-utils/catalog-info.yaml delete mode 100644 packages/techdocs-cli-embedded-app/cypress.json delete mode 100644 packages/techdocs-cli-embedded-app/cypress/.eslintrc.json delete mode 100644 packages/techdocs-cli-embedded-app/cypress/integration/app.js delete mode 100644 packages/techdocs-cli/cypress.config.js delete mode 100644 packages/techdocs-cli/cypress/.eslintrc.json delete mode 100644 packages/techdocs-cli/cypress/e2e/__image_snapshots__/TechDocs Live Preview - Backstage Serve toMatchImageSnapshot - Backstage TechDocs Page #0.png delete mode 100644 packages/techdocs-cli/cypress/e2e/__image_snapshots__/TechDocs Live Preview - MkDocs Serve toMatchImageSnapshot - MkDocs Page #0.png delete mode 100644 packages/techdocs-cli/cypress/e2e/backstage_serve.cy.js delete mode 100644 packages/techdocs-cli/cypress/e2e/mkdocs_serve.cy.js delete mode 100644 packages/techdocs-cli/cypress/fixtures/example.json delete mode 100644 packages/techdocs-cli/cypress/screenshots/backstage_serve.js/TechDocs Live Preview - Backstage Serve toMatchImageSnapshot - Backstage Header #0.png delete mode 100644 packages/techdocs-cli/cypress/screenshots/backstage_serve.js/TechDocs Live Preview - Backstage Serve toMatchImageSnapshot - Backstage TechDocs Page #0 (1).png delete mode 100644 packages/techdocs-cli/cypress/screenshots/backstage_serve.js/TechDocs Live Preview - Backstage Serve toMatchImageSnapshot - Backstage TechDocs Page #0 (2).png delete mode 100644 packages/techdocs-cli/cypress/screenshots/backstage_serve.js/TechDocs Live Preview - Backstage Serve toMatchImageSnapshot - Backstage TechDocs Page #0.png delete mode 100644 packages/techdocs-cli/cypress/support/commands.js delete mode 100644 packages/techdocs-cli/cypress/support/e2e.js diff --git a/.dockerignore b/.dockerignore index e43b5fab1e..78aa97942d 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,7 +2,6 @@ .yarn/cache .yarn/install-state.gz docs -cypress microsite node_modules packages/*/src diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index aa2c7d3b7f..a0ba1163f3 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -8,7 +8,6 @@ yarn.lock @backstage/maintainers @backstage-service */yarn.lock @backstage/maintainers @backstage-service /.changeset/*.md -/cypress/src/integration/plugins/techdocs.spec.ts @backstage/techdocs-maintainers /docs/assets/search @backstage/discoverability-maintainers /docs/features/search @backstage/discoverability-maintainers /docs/features/techdocs @backstage/techdocs-maintainers diff --git a/.gitignore b/.gitignore index c0bf195947..4ad888b46c 100644 --- a/.gitignore +++ b/.gitignore @@ -144,9 +144,6 @@ site # Sensitive credentials *-credentials.yaml -# e2e tests -cypress/cypress/* - # Possible leftover from build:api-reports tsconfig.tmp.json diff --git a/app-config.yaml b/app-config.yaml index 9e153e5763..a2ee232516 100644 --- a/app-config.yaml +++ b/app-config.yaml @@ -291,9 +291,6 @@ catalog: target: ../../plugins/scaffolder-backend/sample-templates/all-templates.yaml rules: - allow: [Template] - # Backstage end-to-end tests of TechDocs - - type: file - target: ../../cypress/e2e-fixture.catalog.info.yaml scaffolder: # Use to customize default commit author info used when new components are created # defaultAuthor: diff --git a/cypress/.eslintrc.js b/cypress/.eslintrc.js deleted file mode 100644 index 07f264452d..0000000000 --- a/cypress/.eslintrc.js +++ /dev/null @@ -1,9 +0,0 @@ -module.exports = { - extends: [require.resolve('@backstage/cli/config/eslint.backend')], - rules: { - 'no-console': 0, - 'jest/valid-expect': 'off', - 'jest/expect-expect': 'off', - 'no-restricted-syntax': 'off', - }, -}; diff --git a/cypress/.npmrc b/cypress/.npmrc deleted file mode 100644 index c3c66347fd..0000000000 --- a/cypress/.npmrc +++ /dev/null @@ -1,2 +0,0 @@ -registry=https://registry.npmjs.org/ -engine-strict=true diff --git a/cypress/.yarnrc b/cypress/.yarnrc deleted file mode 100644 index a2c82b2833..0000000000 --- a/cypress/.yarnrc +++ /dev/null @@ -1,5 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - -registry "https://registry.npmjs.org/" -network-timeout 300000 diff --git a/cypress/README.md b/cypress/README.md deleted file mode 100644 index be2960e63c..0000000000 --- a/cypress/README.md +++ /dev/null @@ -1,34 +0,0 @@ -# Cypress Tests for Backstage - -Hey 👋 Welcome to the Cypress tests for Backstage. They're designed to be run against the `packages/app` folder in the main repo, and be some form of smoke tests to make sure that we don't break any core functionality. - -### Running Locally - -In order to make typescript happy, this `cypress` package is separate from all the Jest dependencies in the monorepo workspaces setup. - -You can run the e2e tests locally pointing at your local running version like so: - -```sh -cd cypress -yarn install -yarn cypress run -``` - -Note that the tests expect to run against a built application, so you'll want to -run a Docker image and either create an `app-config.cypress.yaml` or pass the -necessary environment variables: - -```sh -yarn tsc -yarn build:backend -yarn workspace example-backend build-image -docker run -p 7007:7007 example-backend -``` - -You can open up the `cypress` console by using `yarn cypress open`. - -You can also run towards any Backstage installation by using the Cypress Environment Variable overrides. - -```sh -CYPRESS_baseUrl="http://demo.backstage.io" yarn cypress run -``` diff --git a/cypress/cypress.json b/cypress/cypress.json deleted file mode 100644 index 7335d0f62a..0000000000 --- a/cypress/cypress.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "baseUrl": "http://localhost:7007", - "integrationFolder": "./src/integration", - "supportFile": "./src/support", - "fixturesFolder": "./src/fixtures", - "pluginsFile": "./src/plugins", - "defaultCommandTimeout": 10000, - "viewportHeight": 900, - "viewportWidth": 1440 -} diff --git a/cypress/e2e-fixture.catalog.info.yaml b/cypress/e2e-fixture.catalog.info.yaml deleted file mode 100644 index 31502e415d..0000000000 --- a/cypress/e2e-fixture.catalog.info.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: techdocs-e2e-fixture - description: Used for end-to-end tests of TechDocs in Backstage. - annotations: - backstage.io/techdocs-ref: dir:./fixtures -spec: - type: service - lifecycle: experimental - owner: user:guest diff --git a/cypress/fixtures/docs/index.md b/cypress/fixtures/docs/index.md deleted file mode 100644 index d7ff14b46d..0000000000 --- a/cypress/fixtures/docs/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# Home page - -This is a basic documentation used for end-to-end tests. diff --git a/cypress/fixtures/docs/sub-page-one.md b/cypress/fixtures/docs/sub-page-one.md deleted file mode 100644 index 7c451efeb5..0000000000 --- a/cypress/fixtures/docs/sub-page-one.md +++ /dev/null @@ -1,109 +0,0 @@ -# Sub-page 1 - -## Section 1.1 - -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! - -## Section 1.2 - -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! - -## Section 1.3 - -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! diff --git a/cypress/fixtures/docs/sub-page-three.md b/cypress/fixtures/docs/sub-page-three.md deleted file mode 100644 index e9a439ed98..0000000000 --- a/cypress/fixtures/docs/sub-page-three.md +++ /dev/null @@ -1,121 +0,0 @@ -# Sub-page 3 - -## Section 3.1 - -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! - -## Section 3.2 - -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! - -### Sub-Section 3.2.1 - -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! - -### Sub-Section 3.2.2 - -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! - -## Section 3.3 - -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! diff --git a/cypress/fixtures/docs/sub-page-two.md b/cypress/fixtures/docs/sub-page-two.md deleted file mode 100644 index eb2344e9c3..0000000000 --- a/cypress/fixtures/docs/sub-page-two.md +++ /dev/null @@ -1,146 +0,0 @@ -# Sub-page 2 - -## Section 2.1 - -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! - -## Section 2.2 - -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! - -### Sub-Section 2.2.1 - -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! - -### Sub-Section 2.2.2 - -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! - -## Section 2.3 - -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! -To next page! - -[Link to Section 1.1](sub-page-one.md#section-11) diff --git a/cypress/fixtures/mkdocs.yml b/cypress/fixtures/mkdocs.yml deleted file mode 100644 index 071d147509..0000000000 --- a/cypress/fixtures/mkdocs.yml +++ /dev/null @@ -1,13 +0,0 @@ -site_name: e2e Fixture Documentation -site_description: Documentation used for end-to-end tests of TechDocs in Backstage. -repo_url: https://github.com/backstage/backstage -edit_uri: edit/master/cypress/fixtures/docs - -nav: - - Home: index.md - - Sub-page 1: sub-page-one.md - - Sub-page 2: sub-page-two.md - - Nested Sub-pages: - - Sub-page 3: sub-page-three.md -plugins: - - techdocs-core diff --git a/cypress/package.json b/cypress/package.json deleted file mode 100644 index fcdf084659..0000000000 --- a/cypress/package.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "@backstage/cypress-tests", - "version": "1.0.0", - "main": "index.js", - "license": "MIT", - "private": true, - "dependencies": { - "cypress": "^12.0.0", - "typescript": "~5.0.0" - } -} diff --git a/cypress/src/fixtures/.gitkeep b/cypress/src/fixtures/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/cypress/src/integration/integrations.spec.ts b/cypress/src/integration/integrations.spec.ts deleted file mode 100644 index 4703c18881..0000000000 --- a/cypress/src/integration/integrations.spec.ts +++ /dev/null @@ -1,82 +0,0 @@ -/* - * 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 'os'; - -describe('Integrations', () => { - describe('ReadTree', () => { - it('should work for github', () => { - cy.loginAsGuest(); - - cy.request('POST', '/api/catalog/locations', { - target: - 'https://github.com/backstage-verification/test-repo/blob/main/**/*', - type: 'url', - }); - - cy.wait(5000); - - cy.visit('/catalog'); - cy.get('[data-testid="user-picker-all"]').click(); - cy.get('table').should('contain', 'github-repo'); - cy.get('table').should('contain', 'github-repo-nested'); - }); - - // it('should work for azure', () => { - // cy.loginAsGuest(); - - // cy.request('POST', '/api/catalog/locations', { - // target: - // 'https://dev.azure.com/backstage-verification/_git/test-repo?path=*', - // type: 'url', - // }); - // }); - - it('should work for gitlab', () => { - cy.loginAsGuest(); - - cy.request('POST', '/api/catalog/locations', { - target: - 'https://gitlab.com/backstage-verification/test-repo/-/tree/master/**/*', - type: 'url', - }); - - cy.wait(5000); - - cy.visit('/catalog'); - cy.get('[data-testid="user-picker-all"]').click(); - cy.get('table').should('contain', 'gitlab-repo'); - cy.get('table').should('contain', 'gitlab-repo-nested'); - }); - - it('should work for bitbucket', () => { - cy.loginAsGuest(); - - cy.request('POST', '/api/catalog/locations', { - target: - 'https://bitbucket.org/backstage-verification/test-repo/src/master/**/*', - type: 'url', - }); - - cy.wait(5000); - - cy.visit('/catalog'); - cy.get('[data-testid="user-picker-all"]').click(); - cy.get('table').should('contain', 'bitbucket-repo'); - cy.get('table').should('contain', 'bitbucket-repo-nested'); - }); - }); -}); diff --git a/cypress/src/integration/plugins/catalog.spec.ts b/cypress/src/integration/plugins/catalog.spec.ts deleted file mode 100644 index 50ef3145e5..0000000000 --- a/cypress/src/integration/plugins/catalog.spec.ts +++ /dev/null @@ -1,199 +0,0 @@ -/* - * 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 'os'; - -describe('Catalog', () => { - describe('default entities', () => { - it('displays the correct amount of entities from default config', () => { - cy.loginAsGuest(); - - cy.visit('/catalog'); - - cy.contains('Owned (10)').should('be.visible'); - }); - - it('Should navigate to a docs tab', () => { - cy.loginAsGuest(); - - cy.visit('/catalog'); - - cy.contains('techdocs-e2e-fixture').click(); - - cy.location().should(loc => { - expect(loc.pathname).to.eq( - '/catalog/default/component/techdocs-e2e-fixture', - ); - }); - - cy.getCatalogDocsTab().click(); - - cy.getTechDocsShadowRoot() - .find('h1') - .contains('Home page') - .should('be.visible'); - }); - - it('Should navigate to a sub-route in docs tab', () => { - cy.loginAsGuest(); - - cy.visit('/catalog'); - - cy.contains('techdocs-e2e-fixture').click(); - - cy.location().should(loc => { - expect(loc.pathname).to.eq( - '/catalog/default/component/techdocs-e2e-fixture', - ); - }); - - cy.getCatalogDocsTab().click(); - - cy.getTechDocsShadowRoot() - .find('h1') - .contains('Home page') - .should('be.visible'); - - cy.getTechDocsShadowRoot().within(() => { - cy.getTechDocsNavigation().find('a').contains('Sub-page 1').click(); - }); - - cy.location().should(loc => { - expect(loc.pathname).to.eq( - '/catalog/default/component/techdocs-e2e-fixture/docs/sub-page-one/', - ); - }); - - cy.getTechDocsShadowRoot() - .find('h1') - .contains('Sub-page 1') - .should('be.visible'); - }); - - it('Should render addons on docs tab homepage', () => { - cy.loginAsGuest(); - - cy.visit('/catalog'); - - cy.contains('techdocs-e2e-fixture').click(); - - cy.location().should(loc => { - expect(loc.pathname).to.eq( - '/catalog/default/component/techdocs-e2e-fixture', - ); - }); - - cy.getCatalogDocsTab().click(); - - cy.wait(300); - - cy.getTechDocsShadowRoot() - .find('h1') - .contains('Home page') - .should('be.visible'); - - // highlight a snippet of text - cy.getTechDocsShadowRoot() - .find('article > p') - .then($el => { - const el = $el[0]; - const document = el.ownerDocument; - const range = document.createRange(); - range.selectNodeContents(el); - document?.getSelection()?.removeAllRanges(); - document?.getSelection()?.addRange(range); - }); - - cy.document().trigger('selectionchange'); - - // wait for new issue default debounce time - cy.wait(600); - - // assert that the new issue button has a right url - cy.getTechDocsShadowRoot() - .contains('Open new Github issue') - .should( - 'have.attr', - 'href', - 'https://github.com/backstage/backstage/issues/new?title=Documentation%20feedback%3A%20This%20is%20a%20basic%20documentation%20used%20for%20end-to-end%20tests.&body=%23%23%20Documentation%20Feedback%20%F0%9F%93%9D%0A%0A%20%23%23%23%23%20The%20highlighted%20text%3A%20%0A%0A%20%3E%20This%20is%20a%20basic%20documentation%20used%20for%20end-to-end%20tests.%0A%0A%20%23%23%23%23%20The%20comment%20on%20the%20text%3A%20%0A%20_%3Ereplace%20this%20line%20with%20your%20comment%3C_%0A%0A%20___%0ABackstage%20URL%3A%20%3Chttp%3A%2F%2Flocalhost%3A7007%2Fcatalog%2Fdefault%2Fcomponent%2Ftechdocs-e2e-fixture%2Fdocs%3E%20%0AMarkdown%20URL%3A%20%3Chttps%3A%2F%2Fgithub.com%2Fbackstage%2Fbackstage%2Fblob%2Fmaster%2Fcypress%2Ffixtures%2Fdocs%2Findex.md%3E', - ); - }); - - it('Should render addons on docs tab sup-page', () => { - cy.loginAsGuest(); - - cy.visit('/catalog'); - - cy.contains('techdocs-e2e-fixture').click(); - - cy.location().should(loc => { - expect(loc.pathname).to.eq( - '/catalog/default/component/techdocs-e2e-fixture', - ); - }); - - cy.getCatalogDocsTab().click(); - - cy.wait(300); - - cy.getTechDocsShadowRoot() - .find('h1') - .contains('Home page') - .should('be.visible'); - - cy.getTechDocsShadowRoot().within(() => { - cy.getTechDocsNavigation().find('a').contains('Sub-page 1').click(); - }); - - cy.location().should(loc => { - expect(loc.pathname).to.eq( - '/catalog/default/component/techdocs-e2e-fixture/docs/sub-page-one/', - ); - }); - - cy.getTechDocsShadowRoot() - .find('h1') - .contains('Sub-page 1') - .should('be.visible'); - - // highlight a snippet of text - cy.getTechDocsShadowRoot() - .find('#section-11') - .then($el => { - const el = $el[0]; - const document = el.ownerDocument; - const range = document.createRange(); - range.selectNodeContents(el); - document?.getSelection()?.removeAllRanges(); - document?.getSelection()?.addRange(range); - }); - - cy.document().trigger('selectionchange'); - - // wait for new issue default debounce time - cy.wait(600); - - // assert that the new issue button has a right url - cy.getTechDocsShadowRoot() - .contains('Open new Github issue') - .should( - 'have.attr', - 'href', - 'https://github.com/backstage/backstage/issues/new?title=Documentation%20feedback%3A%20Section%201.1%C2%B6&body=%23%23%20Documentation%20Feedback%20%F0%9F%93%9D%0A%0A%20%23%23%23%23%20The%20highlighted%20text%3A%20%0A%0A%20%3E%20Section%201.1%C2%B6%0A%0A%20%23%23%23%23%20The%20comment%20on%20the%20text%3A%20%0A%20_%3Ereplace%20this%20line%20with%20your%20comment%3C_%0A%0A%20___%0ABackstage%20URL%3A%20%3Chttp%3A%2F%2Flocalhost%3A7007%2Fcatalog%2Fdefault%2Fcomponent%2Ftechdocs-e2e-fixture%2Fdocs%2Fsub-page-one%2F%3E%20%0AMarkdown%20URL%3A%20%3Chttps%3A%2F%2Fgithub.com%2Fbackstage%2Fbackstage%2Fblob%2Fmaster%2Fcypress%2Ffixtures%2Fdocs%2Fsub-page-one.md%3E', - ); - }); - }); -}); diff --git a/cypress/src/integration/plugins/score-card.spec.ts b/cypress/src/integration/plugins/score-card.spec.ts deleted file mode 100644 index 5871a094e1..0000000000 --- a/cypress/src/integration/plugins/score-card.spec.ts +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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 'os'; - -describe('score-card', () => { - describe('Score board', () => { - it('displays the score board based on sample data', () => { - cy.loginAsGuest(); - - cy.visit('/score-board'); - cy.screenshot({ capture: 'viewport' }); - - cy.contains('System scores overview').should('be.visible'); - cy.checkForErrors(); - cy.get('span:contains("1-2 of 2")').should('be.visible'); // beware, there is also a hidden

element - cy.contains('audio-playback').should('be.visible'); - cy.contains('team-c').should('be.visible'); - cy.contains('non-valid-system').should('be.visible'); - cy.contains('Name').should('be.visible'); - cy.contains('Date').should('be.visible'); - cy.contains('Code').should('be.visible'); - cy.contains('Documentation').should('be.visible'); - cy.contains('Operations').should('be.visible'); - cy.contains('Quality').should('be.visible'); - cy.contains('Security').should('be.visible'); - cy.contains('Total').should('be.visible'); - cy.contains('50 %').should('be.visible'); - cy.contains('75 %').should('be.visible'); - cy.log('navigating to score card detail for audio-playback'); - cy.get('a[data-id="audio-playback"]').should('be.visible').click(); - cy.screenshot({ capture: 'viewport' }); - - cy.url().should( - 'include', - '/catalog/default/System/audio-playback/score', - ); - cy.contains('Scoring').should('be.visible'); - cy.contains('Total score: 57 %').should('be.visible'); - cy.contains('Code').should('be.visible'); - cy.contains('90 %').should('be.visible'); - cy.contains('Documentation').should('be.visible'); - cy.contains('75 %').should('be.visible'); - cy.contains('Operations').should('be.visible'); - cy.contains('50 %').should('be.visible'); - cy.contains('Quality').should('be.visible'); - cy.contains('25 %').should('be.visible'); - cy.contains('Security'); - cy.contains('10 %').should('be.visible'); - cy.checkForErrors(); - - cy.log( - 'Clicking on button [>] that is first child of the element (td) with value=Code', - ); - cy.get('[value="Code"] > button:first-child').click(); - cy.checkForErrors(); - cy.screenshot({ capture: 'viewport' }); - - cy.log('Clicking on link for Code'); - cy.contains('hints: Gitflow: 100%').should('be.visible'); - cy.get('a[data-id="2157"]') - .should('be.visible') - .should( - 'have.attr', - 'href', - 'https://TBD/XXX/_wiki/wikis/XXX.wiki/2157', - ); - }); - }); -}); diff --git a/cypress/src/integration/plugins/techdocs.spec.ts b/cypress/src/integration/plugins/techdocs.spec.ts deleted file mode 100644 index 31094cb128..0000000000 --- a/cypress/src/integration/plugins/techdocs.spec.ts +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright 2020 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 'os'; - -describe('TechDocs', () => { - beforeEach(() => { - cy.loginAsGuest(); - cy.mockSockJSNode(); - cy.interceptTechDocsAPICalls(); - }); - - describe('Navigating to TechDocs', () => { - it('should navigate to the TechDocs home page via the primary navigation bar', () => { - cy.visit('/'); - cy.wait(500); - - cy.get('[data-testid="sidebar-root"]') - .get('div') - .get('a[href="/docs"]') - .click(); - - cy.contains('Documentation'); - }); - - it('should navigate to the TechDocs home page from the URL', () => { - cy.visit('/docs'); - - cy.wait(500); - - cy.contains('Documentation'); - }); - - it('should navigate to a specific TechDocs entity from the "Overview" tab', () => { - cy.visit('/docs'); - - cy.contains('techdocs-e2e-fixture').click(); - - cy.location().should(loc => { - expect(loc.pathname).to.eq( - '/docs/default/component/techdocs-e2e-fixture', - ); - }); - }); - - it('should navigate to a specific TechDocs entity page from a URL', () => { - cy.visit('/docs/default/Component/techdocs-e2e-fixture'); - cy.waitHomePage(); - - cy.contains('e2e Fixture Documentation'); - cy.contains( - 'Documentation used for end-to-end tests of TechDocs in Backstage.', - ); - cy.getTechDocsShadowRoot().contains('Home page'); - }); - - it('should navigate to a specific TechDocs section from a URL', () => { - cy.visit('/docs/default/Component/techdocs-e2e-fixture/sub-page-two'); - cy.waitSectionTwoPage(); - - cy.window().its('scrollY').should('equal', 0); - - cy.getTechDocsShadowRoot().within(() => { - cy.contains('Sub-page 2'); - }); - }); - - it('should navigate to a specific TechDocs fragment from a URL', () => { - cy.visit( - '/docs/default/Component/techdocs-e2e-fixture/sub-page-two#section-23', - ); - - // This is used to test the post-render behavior of the techdocs Reader - cy.wait(500); - - cy.getTechDocsShadowRoot().within(() => { - cy.isInViewport('#section-23'); - }); - }); - - it('should navigate to a wrong TechDocs entity page from a URL', () => { - cy.visit('/docs/default/Component/wrong-component'); - - cy.get('[data-testid=error]').should('be.visible'); - }); - }); - - describe('Rendering TechDocs Addons', () => { - it('should render a content addon in homepage', () => { - cy.visit('/docs/default/Component/techdocs-e2e-fixture'); - - cy.contains('e2e Fixture Documentation'); - - // highlight a snippet of text - cy.getTechDocsShadowRoot() - .find('article > p') - .then($el => { - const el = $el[0]; - const document = el.ownerDocument; - const range = document.createRange(); - range.selectNodeContents(el); - document?.getSelection()?.removeAllRanges(); - document?.getSelection()?.addRange(range); - }); - - cy.document().trigger('selectionchange'); - - // wait for new issue default debounce time - cy.wait(600); - - // assert that the new issue button has a right url - cy.getTechDocsShadowRoot() - .contains('Open new Github issue') - .should( - 'have.attr', - 'href', - 'https://github.com/backstage/backstage/issues/new?title=Documentation%20feedback%3A%20This%20is%20a%20basic%20documentation%20used%20for%20end-to-end%20tests.&body=%23%23%20Documentation%20Feedback%20%F0%9F%93%9D%0A%0A%20%23%23%23%23%20The%20highlighted%20text%3A%20%0A%0A%20%3E%20This%20is%20a%20basic%20documentation%20used%20for%20end-to-end%20tests.%0A%0A%20%23%23%23%23%20The%20comment%20on%20the%20text%3A%20%0A%20_%3Ereplace%20this%20line%20with%20your%20comment%3C_%0A%0A%20___%0ABackstage%20URL%3A%20%3Chttp%3A%2F%2Flocalhost%3A7007%2Fdocs%2Fdefault%2FComponent%2Ftechdocs-e2e-fixture%3E%20%0AMarkdown%20URL%3A%20%3Chttps%3A%2F%2Fgithub.com%2Fbackstage%2Fbackstage%2Fblob%2Fmaster%2Fcypress%2Ffixtures%2Fdocs%2Findex.md%3E', - ); - }); - - it('should render a content addon in sub-pages', () => { - cy.visit('/docs/default/Component/techdocs-e2e-fixture'); - - cy.contains('e2e Fixture Documentation'); - - // open sub-page - cy.getTechDocsShadowRoot().within(() => { - cy.getTechDocsNavigation().find('a').contains('Sub-page 1').click(); - }); - - // highlight a snippet of text - cy.getTechDocsShadowRoot() - .find('#section-11') - .then($el => { - const el = $el[0]; - const document = el.ownerDocument; - const range = document.createRange(); - range.selectNodeContents(el); - document?.getSelection()?.removeAllRanges(); - document?.getSelection()?.addRange(range); - }); - - cy.document().trigger('selectionchange'); - - // wait for new issue default debounce time - cy.wait(600); - - // assert that the new issue button has a right url - cy.getTechDocsShadowRoot() - .contains('Open new Github issue') - .should( - 'have.attr', - 'href', - 'https://github.com/backstage/backstage/issues/new?title=Documentation%20feedback%3A%20Section%201.1%C2%B6&body=%23%23%20Documentation%20Feedback%20%F0%9F%93%9D%0A%0A%20%23%23%23%23%20The%20highlighted%20text%3A%20%0A%0A%20%3E%20Section%201.1%C2%B6%0A%0A%20%23%23%23%23%20The%20comment%20on%20the%20text%3A%20%0A%20_%3Ereplace%20this%20line%20with%20your%20comment%3C_%0A%0A%20___%0ABackstage%20URL%3A%20%3Chttp%3A%2F%2Flocalhost%3A7007%2Fdocs%2Fdefault%2FComponent%2Ftechdocs-e2e-fixture%2Fsub-page-one%2F%3E%20%0AMarkdown%20URL%3A%20%3Chttps%3A%2F%2Fgithub.com%2Fbackstage%2Fbackstage%2Fblob%2Fmaster%2Fcypress%2Ffixtures%2Fdocs%2Fsub-page-one.md%3E', - ); - }); - }); - - describe('Navigating within TechDocs', () => { - it('should navigate to a specific TechDocs page via the navigation bar', () => { - cy.visit('/docs/default/Component/techdocs-e2e-fixture'); - - cy.getTechDocsShadowRoot().within(() => { - cy.getTechDocsNavigation() - .find('> div > div > [data-md-level="0"] > ul > li:nth-child(2) > a') - .click(); - cy.contains('Sub-page 1'); - cy.window().its('scrollY').should('eq', 0); - }); - }); - - describe('Navigating within a TechDocs page', () => { - beforeEach(() => { - cy.visit('/docs/default/Component/techdocs-e2e-fixture/sub-page-two'); - }); - - it('should navigate to a specific fragment within the page via the table of contents - Level 1', () => { - return cy.getTechDocsShadowRoot().within(() => { - // Section 3 - cy.getTechDocsTableOfContents() - .find('a') - .contains('Section 2.3') - .click(); - - // wait scroll timeout - cy.wait(500); - - cy.isInViewport('#section-23'); - }); - }); - - it('should navigate to a specific fragment within the page via the table of contents - Level 2', () => { - return cy.getTechDocsShadowRoot().within(() => { - cy.isNotInViewport('#sub-section-222'); - // Section 2.2 - cy.getTechDocsTableOfContents() - .find('a') - .contains('Section 2.2.2') - .click(); - - // wait scroll timeout - cy.wait(500); - - cy.isInViewport('#sub-section-222'); - }); - }); - - it('should navigate to a specific TechDocs page fragment from a link', () => { - return cy.getTechDocsShadowRoot().within(() => { - cy.get('article').contains('Link to Section 1.1').click(); - - cy.location().should(loc => { - expect(loc.pathname).to.eq( - '/docs/default/Component/techdocs-e2e-fixture/sub-page-one/', - ); - expect(loc.hash).to.eq('#section-11'); - }); - }); - }); - - it('should navigate to the next page within a TechDocs entity', () => { - return cy.getTechDocsShadowRoot().within(() => { - cy.get('footer a').contains('Sub-page 3').click(); - - cy.location().should(loc => { - expect(loc.pathname).to.eq( - '/docs/default/Component/techdocs-e2e-fixture/sub-page-three/', - ); - }); - }); - }); - - it('should navigate to the previous page within a TechDocs entity', () => { - return cy.getTechDocsShadowRoot().within(() => { - cy.get('footer a').contains('Sub-page 1').click(); - - cy.location().should(loc => { - expect(loc.pathname).to.eq( - '/docs/default/Component/techdocs-e2e-fixture/sub-page-one/', - ); - }); - }); - }); - }); - }); -}); diff --git a/cypress/src/integration/user/login.spec.ts b/cypress/src/integration/user/login.spec.ts deleted file mode 100644 index 8e84ebbf06..0000000000 --- a/cypress/src/integration/user/login.spec.ts +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2020 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 'os'; - -describe('Login', () => { - it('should render the login page', () => { - cy.visit('/'); - cy.contains('Select a sign-in method'); - }); - - it('should be able to login', () => { - cy.get('button').contains('Enter').click(); - cy.url().should('include', '/catalog'); - - cy.contains('artist-lookup'); - }); -}); diff --git a/cypress/src/integration/user/logout.spec.ts b/cypress/src/integration/user/logout.spec.ts deleted file mode 100644 index a3aea9d6a8..0000000000 --- a/cypress/src/integration/user/logout.spec.ts +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2020 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 'os'; - -describe('Logout', () => { - before(() => { - cy.loginAsGuest(); - }); - it('should be able to logout', () => { - cy.visit('/settings'); - cy.get('[data-testid="user-settings-menu"]').click(); - return cy - .get('[data-testid="sign-out"]') - .click() - .then(() => { - return expect( - localStorage.getItem('@backstage/core:SignInPage:provider'), - ).to.be.null; - }); - }); -}); diff --git a/cypress/src/plugins/index.ts b/cypress/src/plugins/index.ts deleted file mode 100644 index 4c8a35f0d1..0000000000 --- a/cypress/src/plugins/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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 default () => {}; diff --git a/cypress/src/support/commands.ts b/cypress/src/support/commands.ts deleted file mode 100644 index 62e21a5bef..0000000000 --- a/cypress/src/support/commands.ts +++ /dev/null @@ -1,125 +0,0 @@ -/* - * 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. - */ -/* eslint-disable jest/no-standalone-expect */ -/// -import 'os'; - -Cypress.Commands.add('loginAsGuest', () => { - cy.visit('/', { - onLoad: (win: Window) => - win.localStorage.setItem('@backstage/core:SignInPage:provider', 'guest'), - }); -}); - -Cypress.Commands.add('getTechDocsShadowRoot', () => { - cy.get('[data-testid="techdocs-native-shadowroot"]').shadow(); -}); - -Cypress.Commands.add('isNotInViewport', element => { - cy.get(element).then($el => { - const bottom = Cypress.config(`viewportHeight`); - const rect = $el[0].getBoundingClientRect(); - - if (bottom) { - expect(rect.top).to.be.greaterThan(bottom); - expect(rect.bottom).to.be.greaterThan(bottom); - expect(rect.top).to.be.greaterThan(bottom); - expect(rect.bottom).to.be.greaterThan(bottom); - } - }); -}); - -Cypress.Commands.add('isInViewport', element => { - cy.get(element).then($el => { - const bottom = Cypress.config(`viewportHeight`); - const rect = $el[0].getBoundingClientRect(); - - if (bottom) { - expect(rect.top).not.to.be.greaterThan(bottom); - expect(rect.bottom).not.to.be.greaterThan(bottom); - expect(rect.top).not.to.be.greaterThan(bottom); - expect(rect.bottom).not.to.be.greaterThan(bottom); - } - }); -}); - -Cypress.Commands.add('getTechDocsTableOfContents', () => { - cy.get('[data-md-type="toc"]'); -}); - -Cypress.Commands.add('getTechDocsNavigation', () => { - cy.get('[data-md-type="navigation"]'); -}); - -Cypress.Commands.add('getCatalogDocsTab', () => { - cy.get('button[role="tab"]').contains('Docs'); -}); - -Cypress.Commands.add('mockSockJSNode', () => { - cy.intercept('GET', '**/sockjs-node/info**', { - body: { - websocket: true, - origins: ['*:*'], - cookie_needed: false, - entropy: 2882389500, - }, - }); -}); - -Cypress.Commands.add('interceptTechDocsAPICalls', () => { - cy.intercept( - 'GET', - '**/techdocs/metadata/entity/default/Component/techdocs-e2e-fixture', - ).as('entityMetadata'); - - cy.intercept( - 'GET', - '**/techdocs/metadata/techdocs/default/Component/techdocs-e2e-fixture', - ).as('techdocsMetadata'); - - cy.intercept( - 'GET', - '**/techdocs/sync/default/Component/techdocs-e2e-fixture', - ).as('syncEntity'); - - cy.intercept( - 'GET', - '**/techdocs/static/docs/default/Component/techdocs-e2e-fixture/sub-page-two/index.html', - ).as('sectionTwoHTML'); - - cy.intercept( - 'GET', - '**/techdocs/static/docs/default/Component/techdocs-e2e-fixture/index.html', - ).as('homeHTML'); -}); - -Cypress.Commands.add('waitSectionTwoPage', () => { - cy.wait([ - '@entityMetadata', - '@syncEntity', - '@techdocsMetadata', - '@sectionTwoHTML', - ]); -}); - -Cypress.Commands.add('waitHomePage', () => { - cy.wait(['@entityMetadata', '@syncEntity', '@techdocsMetadata', '@homeHTML']); -}); - -Cypress.Commands.add('checkForErrors', () => { - // when an error occurs there is a

with an "alert" role attribute. This can change ofc => we shall add also some positive ("when error occurs") test - cy.get('div[role="alert"]').should('not.exist'); -}); diff --git a/cypress/src/support/index.ts b/cypress/src/support/index.ts deleted file mode 100644 index 6d1051a793..0000000000 --- a/cypress/src/support/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * 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 './commands'; diff --git a/cypress/src/types.d.ts b/cypress/src/types.d.ts deleted file mode 100644 index dca22112e9..0000000000 --- a/cypress/src/types.d.ts +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 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. - */ -declare module 'zombie'; -declare module 'pgtools'; -declare namespace Cypress { - interface Chainable { - /** - * Login as guest - * @example cy.loginAsGuests - */ - loginAsGuest(): Chainable; - /** - * Get the TechDocs shadow root element - * @example cy.getTechDocsShadowRoot - */ - getTechDocsShadowRoot(): Chainable; - /** - * Mock TechDocs backend API - * @example cy.mockTechDocs - */ - mockTechDocs(): void; - /** - * Get the TechDocs table of contents element - * @example cy.getTechDocsShadowRoot - */ - getTechDocsTableOfContents(): Chainable; - /** - * Get the TechDocs navigation element - * @example cy.getTechDocsNavigation - */ - getTechDocsNavigation(): Chainable; - /** - * Get the Catalog docs tab - * @example cy.getCatalogDocsTab - */ - getCatalogDocsTab(): Chainable; - /** - * Intercept the TechDocs API calls - * @example cy.interceptTechDocsAPICalls - */ - interceptTechDocsAPICalls(): Chainable; - /** - * Mock SockJS-Node call - * @example cy.mockSockJSNode - */ - mockSockJSNode(): Chainable; - /** - * Wait TechDocs API response for home page - * @example cy.waitHomePage - */ - waitHomePage(): Chainable; - /** - * Wait TechDocs API response for Section 2 page - * @example cy.waitSectionTwoPage - */ - waitSectionTwoPage(): Chainable; - /** - * Check if the element is in viewport - * @example cy.isInViewport - */ - isInViewport(element: string): Chainable; - /** - * Check if the element is not in viewport - * @example cy.isNotInViewport - */ - isNotInViewport(element: string): Chainable; - /** - * Check if we have not caused error by our last action - * @example cy.checkForErrors - */ - checkForErrors(): Chainable; - } -} diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts deleted file mode 100644 index fd4db77d61..0000000000 --- a/cypress/support/commands.ts +++ /dev/null @@ -1,52 +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. - */ - -// *********************************************** -// This example commands.ts shows you how to -// create various custom commands and overwrite -// existing commands. -// -// For more comprehensive examples of custom -// commands please read more here: -// https://on.cypress.io/custom-commands -// *********************************************** -// -// -// -- This is a parent command -- -// Cypress.Commands.add('login', (email, password) => { ... }) -// -// -// -- This is a child command -- -// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) -// -// -// -- This is a dual command -- -// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) -// -// -// -- This will overwrite an existing command -- -// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) -// -// declare global { -// namespace Cypress { -// interface Chainable { -// login(email: string, password: string): Chainable -// drag(subject: string, options?: Partial): Chainable -// dismiss(subject: string, options?: Partial): Chainable -// visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable -// } -// } -// } diff --git a/cypress/support/e2e.ts b/cypress/support/e2e.ts deleted file mode 100644 index c71790471e..0000000000 --- a/cypress/support/e2e.ts +++ /dev/null @@ -1,35 +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. - */ - -// This example support/e2e.ts is processed and -// loaded automatically before your test files. -// -// This is a great place to put global configuration and -// behavior that modifies Cypress. -// -// You can change the location of this file or turn off -// automatically serving support files with the -// 'supportFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/configuration -// *********************************************************** - -// Import commands.js using ES2015 syntax: -import './commands'; - -// Alternatively you can use CommonJS syntax: -// require('./commands') diff --git a/cypress/tsconfig.json b/cypress/tsconfig.json deleted file mode 100644 index 9c4a63b76c..0000000000 --- a/cypress/tsconfig.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "compilerOptions": { - "allowJs": true, - "declaration": true, - "declarationMap": false, - "esModuleInterop": true, - "experimentalDecorators": false, - "forceConsistentCasingInFileNames": true, - "importHelpers": false, - "incremental": true, - "isolatedModules": true, - "jsx": "react", - "lib": ["DOM", "DOM.Iterable", "ScriptHost", "ES2021", "ESNext.Promise"], - "module": "ESNext", - "moduleResolution": "node", - "noEmit": true, - "noFallthroughCasesInSwitch": true, - "noImplicitAny": true, - "noImplicitReturns": true, - "noImplicitThis": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "pretty": true, - "removeComments": false, - "resolveJsonModule": true, - "sourceMap": false, - "skipLibCheck": false, - "strict": true, - "strictBindCallApply": true, - "strictFunctionTypes": true, - "strictNullChecks": true, - "strictPropertyInitialization": true, - "stripInternal": true, - "target": "ES2021", - "types": ["node", "cypress"] - } -} diff --git a/cypress/yarn.lock b/cypress/yarn.lock deleted file mode 100644 index 923868f152..0000000000 --- a/cypress/yarn.lock +++ /dev/null @@ -1,1639 +0,0 @@ -# This file is generated by running "yarn install" inside your project. -# Manual changes might be lost - proceed with caution! - -__metadata: - version: 6 - cacheKey: 8 - -"@backstage/cypress-tests@workspace:.": - version: 0.0.0-use.local - resolution: "@backstage/cypress-tests@workspace:." - dependencies: - cypress: ^12.0.0 - typescript: ~5.0.0 - languageName: unknown - linkType: soft - -"@colors/colors@npm:1.5.0": - version: 1.5.0 - resolution: "@colors/colors@npm:1.5.0" - checksum: d64d5260bed1d5012ae3fc617d38d1afc0329fec05342f4e6b838f46998855ba56e0a73833f4a80fa8378c84810da254f76a8a19c39d038260dc06dc4e007425 - languageName: node - linkType: hard - -"@cypress/request@npm:2.88.12": - version: 2.88.12 - resolution: "@cypress/request@npm:2.88.12" - dependencies: - aws-sign2: ~0.7.0 - aws4: ^1.8.0 - caseless: ~0.12.0 - combined-stream: ~1.0.6 - extend: ~3.0.2 - forever-agent: ~0.6.1 - form-data: ~2.3.2 - http-signature: ~1.3.6 - is-typedarray: ~1.0.0 - isstream: ~0.1.2 - json-stringify-safe: ~5.0.1 - mime-types: ~2.1.19 - performance-now: ^2.1.0 - qs: ~6.10.3 - safe-buffer: ^5.1.2 - tough-cookie: ^4.1.3 - tunnel-agent: ^0.6.0 - uuid: ^8.3.2 - checksum: 2c6fbf7f3127d41bffca8374beaa8cf95450495a8a077b00309ea9d94dd2a4da450a77fe038e8ad26c97cdd7c39b65c53c850f8338ce9bc2dbe23ce2e2b48329 - languageName: node - linkType: hard - -"@cypress/xvfb@npm:^1.2.4": - version: 1.2.4 - resolution: "@cypress/xvfb@npm:1.2.4" - dependencies: - debug: ^3.1.0 - lodash.once: ^4.1.1 - checksum: 7bdcdaeb1bb692ec9d9bf8ec52538aa0bead6764753f4a067a171a511807a43fab016f7285a56bef6a606c2467ff3f1365e1ad2d2d583b81beed849ee1573fd1 - languageName: node - linkType: hard - -"@types/node@npm:*": - version: 18.7.14 - resolution: "@types/node@npm:18.7.14" - checksum: 99cf28ff854100158de875cca23c7acc3cc01dfee526a52b90b7f36767c821bcbaf2be0a98a70f06f3b78f3c60639168ff949d725b61e2e124f9f71f1fb8043d - languageName: node - linkType: hard - -"@types/node@npm:^16.18.39": - version: 16.18.53 - resolution: "@types/node@npm:16.18.53" - checksum: 26c05cde59664360c22e0dda70776ca6f1b35f0b94e4f84d2c21e2afa2e69ac3a2c99bbb57b43405f81df1b2598f6d707ccc7c4c31865f90e45c4625d8400518 - languageName: node - linkType: hard - -"@types/sinonjs__fake-timers@npm:8.1.1": - version: 8.1.1 - resolution: "@types/sinonjs__fake-timers@npm:8.1.1" - checksum: ca09d54d47091d87020824a73f026300fa06b17cd9f2f9b9387f28b549364b141ef194ee28db762f6588de71d8febcd17f753163cb7ea116b8387c18e80ebd5c - languageName: node - linkType: hard - -"@types/sizzle@npm:^2.3.2": - version: 2.3.3 - resolution: "@types/sizzle@npm:2.3.3" - checksum: 586a9fb1f6ff3e325e0f2cc1596a460615f0bc8a28f6e276ac9b509401039dd242fa8b34496d3a30c52f5b495873922d09a9e76c50c2ab2bcc70ba3fb9c4e160 - languageName: node - linkType: hard - -"@types/yauzl@npm:^2.9.1": - version: 2.10.0 - resolution: "@types/yauzl@npm:2.10.0" - dependencies: - "@types/node": "*" - checksum: 55d27ae5d346ea260e40121675c24e112ef0247649073848e5d4e03182713ae4ec8142b98f61a1c6cbe7d3b72fa99bbadb65d8b01873e5e605cdc30f1ff70ef2 - languageName: node - linkType: hard - -"aggregate-error@npm:^3.0.0": - version: 3.1.0 - resolution: "aggregate-error@npm:3.1.0" - dependencies: - clean-stack: ^2.0.0 - indent-string: ^4.0.0 - checksum: 1101a33f21baa27a2fa8e04b698271e64616b886795fd43c31068c07533c7b3facfcaf4e9e0cab3624bd88f729a592f1c901a1a229c9e490eafce411a8644b79 - languageName: node - linkType: hard - -"ansi-colors@npm:^4.1.1": - version: 4.1.3 - resolution: "ansi-colors@npm:4.1.3" - checksum: a9c2ec842038a1fabc7db9ece7d3177e2fe1c5dc6f0c51ecfbf5f39911427b89c00b5dc6b8bd95f82a26e9b16aaae2e83d45f060e98070ce4d1333038edceb0e - languageName: node - linkType: hard - -"ansi-escapes@npm:^4.3.0": - version: 4.3.2 - resolution: "ansi-escapes@npm:4.3.2" - dependencies: - type-fest: ^0.21.3 - checksum: 93111c42189c0a6bed9cdb4d7f2829548e943827ee8479c74d6e0b22ee127b2a21d3f8b5ca57723b8ef78ce011fbfc2784350eb2bde3ccfccf2f575fa8489815 - languageName: node - linkType: hard - -"ansi-regex@npm:^5.0.1": - version: 5.0.1 - resolution: "ansi-regex@npm:5.0.1" - checksum: 2aa4bb54caf2d622f1afdad09441695af2a83aa3fe8b8afa581d205e57ed4261c183c4d3877cee25794443fde5876417d859c108078ab788d6af7e4fe52eb66b - languageName: node - linkType: hard - -"ansi-styles@npm:^4.0.0, ansi-styles@npm:^4.1.0": - version: 4.3.0 - resolution: "ansi-styles@npm:4.3.0" - dependencies: - color-convert: ^2.0.1 - checksum: 513b44c3b2105dd14cc42a19271e80f386466c4be574bccf60b627432f9198571ebf4ab1e4c3ba17347658f4ee1711c163d574248c0c1cdc2d5917a0ad582ec4 - languageName: node - linkType: hard - -"arch@npm:^2.2.0": - version: 2.2.0 - resolution: "arch@npm:2.2.0" - checksum: e21b7635029fe8e9cdd5a026f9a6c659103e63fff423834323cdf836a1bb240a72d0c39ca8c470f84643385cf581bd8eda2cad8bf493e27e54bd9783abe9101f - languageName: node - linkType: hard - -"asn1@npm:~0.2.3": - version: 0.2.6 - resolution: "asn1@npm:0.2.6" - dependencies: - safer-buffer: ~2.1.0 - checksum: 39f2ae343b03c15ad4f238ba561e626602a3de8d94ae536c46a4a93e69578826305366dc09fbb9b56aec39b4982a463682f259c38e59f6fa380cd72cd61e493d - languageName: node - linkType: hard - -"assert-plus@npm:1.0.0, assert-plus@npm:^1.0.0": - version: 1.0.0 - resolution: "assert-plus@npm:1.0.0" - checksum: 19b4340cb8f0e6a981c07225eacac0e9d52c2644c080198765d63398f0075f83bbc0c8e95474d54224e297555ad0d631c1dcd058adb1ddc2437b41a6b424ac64 - languageName: node - linkType: hard - -"astral-regex@npm:^2.0.0": - version: 2.0.0 - resolution: "astral-regex@npm:2.0.0" - checksum: 876231688c66400473ba505731df37ea436e574dd524520294cc3bbc54ea40334865e01fa0d074d74d036ee874ee7e62f486ea38bc421ee8e6a871c06f011766 - languageName: node - linkType: hard - -"async@npm:^3.2.0": - version: 3.2.4 - resolution: "async@npm:3.2.4" - checksum: 43d07459a4e1d09b84a20772414aa684ff4de085cbcaec6eea3c7a8f8150e8c62aa6cd4e699fe8ee93c3a5b324e777d34642531875a0817a35697522c1b02e89 - languageName: node - linkType: hard - -"asynckit@npm:^0.4.0": - version: 0.4.0 - resolution: "asynckit@npm:0.4.0" - checksum: 7b78c451df768adba04e2d02e63e2d0bf3b07adcd6e42b4cf665cb7ce899bedd344c69a1dcbce355b5f972d597b25aaa1c1742b52cffd9caccb22f348114f6be - languageName: node - linkType: hard - -"at-least-node@npm:^1.0.0": - version: 1.0.0 - resolution: "at-least-node@npm:1.0.0" - checksum: 463e2f8e43384f1afb54bc68485c436d7622acec08b6fad269b421cb1d29cebb5af751426793d0961ed243146fe4dc983402f6d5a51b720b277818dbf6f2e49e - languageName: node - linkType: hard - -"aws-sign2@npm:~0.7.0": - version: 0.7.0 - resolution: "aws-sign2@npm:0.7.0" - checksum: b148b0bb0778098ad8cf7e5fc619768bcb51236707ca1d3e5b49e41b171166d8be9fdc2ea2ae43d7decf02989d0aaa3a9c4caa6f320af95d684de9b548a71525 - languageName: node - linkType: hard - -"aws4@npm:^1.8.0": - version: 1.11.0 - resolution: "aws4@npm:1.11.0" - checksum: 5a00d045fd0385926d20ebebcfba5ec79d4482fe706f63c27b324d489a04c68edb0db99ed991e19eda09cb8c97dc2452059a34d97545cebf591d7a2b5a10999f - languageName: node - linkType: hard - -"balanced-match@npm:^1.0.0": - version: 1.0.2 - resolution: "balanced-match@npm:1.0.2" - checksum: 9706c088a283058a8a99e0bf91b0a2f75497f185980d9ffa8b304de1d9e58ebda7c72c07ebf01dadedaac5b2907b2c6f566f660d62bd336c3468e960403b9d65 - languageName: node - linkType: hard - -"base64-js@npm:^1.3.1": - version: 1.5.1 - resolution: "base64-js@npm:1.5.1" - checksum: 669632eb3745404c2f822a18fc3a0122d2f9a7a13f7fb8b5823ee19d1d2ff9ee5b52c53367176ea4ad093c332fd5ab4bd0ebae5a8e27917a4105a4cfc86b1005 - languageName: node - linkType: hard - -"bcrypt-pbkdf@npm:^1.0.0": - version: 1.0.2 - resolution: "bcrypt-pbkdf@npm:1.0.2" - dependencies: - tweetnacl: ^0.14.3 - checksum: 4edfc9fe7d07019609ccf797a2af28351736e9d012c8402a07120c4453a3b789a15f2ee1530dc49eee8f7eb9379331a8dd4b3766042b9e502f74a68e7f662291 - languageName: node - linkType: hard - -"blob-util@npm:^2.0.2": - version: 2.0.2 - resolution: "blob-util@npm:2.0.2" - checksum: d543e6b92e4ca715ca33c78e89a07a2290d43e5b2bc897d7ec588c5c7bbf59df93e45225ac0c9258aa6ce4320358990f99c9288f1c48280f8ec5d7a2e088d19b - languageName: node - linkType: hard - -"bluebird@npm:^3.7.2": - version: 3.7.2 - resolution: "bluebird@npm:3.7.2" - checksum: 869417503c722e7dc54ca46715f70e15f4d9c602a423a02c825570862d12935be59ed9c7ba34a9b31f186c017c23cac6b54e35446f8353059c101da73eac22ef - languageName: node - linkType: hard - -"brace-expansion@npm:^1.1.7": - version: 1.1.11 - resolution: "brace-expansion@npm:1.1.11" - dependencies: - balanced-match: ^1.0.0 - concat-map: 0.0.1 - checksum: faf34a7bb0c3fcf4b59c7808bc5d2a96a40988addf2e7e09dfbb67a2251800e0d14cd2bfc1aa79174f2f5095c54ff27f46fb1289fe2d77dac755b5eb3434cc07 - languageName: node - linkType: hard - -"buffer-crc32@npm:~0.2.3": - version: 0.2.13 - resolution: "buffer-crc32@npm:0.2.13" - checksum: 06252347ae6daca3453b94e4b2f1d3754a3b146a111d81c68924c22d91889a40623264e95e67955b1cb4a68cbedf317abeabb5140a9766ed248973096db5ce1c - languageName: node - linkType: hard - -"buffer@npm:^5.6.0": - version: 5.7.1 - resolution: "buffer@npm:5.7.1" - dependencies: - base64-js: ^1.3.1 - ieee754: ^1.1.13 - checksum: e2cf8429e1c4c7b8cbd30834ac09bd61da46ce35f5c22a78e6c2f04497d6d25541b16881e30a019c6fd3154150650ccee27a308eff3e26229d788bbdeb08ab84 - languageName: node - linkType: hard - -"cachedir@npm:^2.3.0": - version: 2.3.0 - resolution: "cachedir@npm:2.3.0" - checksum: ec90cb0f2e6336e266aa748dbadf3da9e0b20e843e43f1591acab7a3f1451337dc2f26cb9dd833ae8cfefeffeeb43ef5b5ff62782a685f4e3c2305dd98482fcb - languageName: node - linkType: hard - -"call-bind@npm:^1.0.0": - version: 1.0.2 - resolution: "call-bind@npm:1.0.2" - dependencies: - function-bind: ^1.1.1 - get-intrinsic: ^1.0.2 - checksum: f8e31de9d19988a4b80f3e704788c4a2d6b6f3d17cfec4f57dc29ced450c53a49270dc66bf0fbd693329ee948dd33e6c90a329519aef17474a4d961e8d6426b0 - languageName: node - linkType: hard - -"caseless@npm:~0.12.0": - version: 0.12.0 - resolution: "caseless@npm:0.12.0" - checksum: b43bd4c440aa1e8ee6baefee8063b4850fd0d7b378f6aabc796c9ec8cb26d27fb30b46885350777d9bd079c5256c0e1329ad0dc7c2817e0bb466810ebb353751 - languageName: node - linkType: hard - -"chalk@npm:^4.1.0": - version: 4.1.2 - resolution: "chalk@npm:4.1.2" - dependencies: - ansi-styles: ^4.1.0 - supports-color: ^7.1.0 - checksum: fe75c9d5c76a7a98d45495b91b2172fa3b7a09e0cc9370e5c8feb1c567b85c4288e2b3fded7cfdd7359ac28d6b3844feb8b82b8686842e93d23c827c417e83fc - languageName: node - linkType: hard - -"check-more-types@npm:^2.24.0": - version: 2.24.0 - resolution: "check-more-types@npm:2.24.0" - checksum: b09080ec3404d20a4b0ead828994b2e5913236ef44ed3033a27062af0004cf7d2091fbde4b396bf13b7ce02fb018bc9960b48305e6ab2304cd82d73ed7a51ef4 - languageName: node - linkType: hard - -"ci-info@npm:^3.2.0": - version: 3.3.2 - resolution: "ci-info@npm:3.3.2" - checksum: fd81f1edd2d3b0f6cb077b2e84365136d87b9db8c055928c1ad69da8a76c2c2f19cba8ea51b90238302157ca927f91f92b653e933f2398dde4867500f08d6e62 - languageName: node - linkType: hard - -"clean-stack@npm:^2.0.0": - version: 2.2.0 - resolution: "clean-stack@npm:2.2.0" - checksum: 2ac8cd2b2f5ec986a3c743935ec85b07bc174d5421a5efc8017e1f146a1cf5f781ae962618f416352103b32c9cd7e203276e8c28241bbe946160cab16149fb68 - languageName: node - linkType: hard - -"cli-cursor@npm:^3.1.0": - version: 3.1.0 - resolution: "cli-cursor@npm:3.1.0" - dependencies: - restore-cursor: ^3.1.0 - checksum: 2692784c6cd2fd85cfdbd11f53aea73a463a6d64a77c3e098b2b4697a20443f430c220629e1ca3b195ea5ac4a97a74c2ee411f3807abf6df2b66211fec0c0a29 - languageName: node - linkType: hard - -"cli-table3@npm:~0.6.1": - version: 0.6.2 - resolution: "cli-table3@npm:0.6.2" - dependencies: - "@colors/colors": 1.5.0 - string-width: ^4.2.0 - dependenciesMeta: - "@colors/colors": - optional: true - checksum: 2f82391698b8a2a2a5e45d2adcfea5d93e557207f90455a8d4c1aac688e9b18a204d9eb4ba1d322fa123b17d64ea3dc5e11de8b005529f3c3e7dbeb27cb4d9be - languageName: node - linkType: hard - -"cli-truncate@npm:^2.1.0": - version: 2.1.0 - resolution: "cli-truncate@npm:2.1.0" - dependencies: - slice-ansi: ^3.0.0 - string-width: ^4.2.0 - checksum: bf1e4e6195392dc718bf9cd71f317b6300dc4a9191d052f31046b8773230ece4fa09458813bf0e3455a5e68c0690d2ea2c197d14a8b85a7b5e01c97f4b5feb5d - languageName: node - linkType: hard - -"color-convert@npm:^2.0.1": - version: 2.0.1 - resolution: "color-convert@npm:2.0.1" - dependencies: - color-name: ~1.1.4 - checksum: 79e6bdb9fd479a205c71d89574fccfb22bd9053bd98c6c4d870d65c132e5e904e6034978e55b43d69fcaa7433af2016ee203ce76eeba9cfa554b373e7f7db336 - languageName: node - linkType: hard - -"color-name@npm:~1.1.4": - version: 1.1.4 - resolution: "color-name@npm:1.1.4" - checksum: b0445859521eb4021cd0fb0cc1a75cecf67fceecae89b63f62b201cca8d345baf8b952c966862a9d9a2632987d4f6581f0ec8d957dfacece86f0a7919316f610 - languageName: node - linkType: hard - -"colorette@npm:^2.0.16": - version: 2.0.19 - resolution: "colorette@npm:2.0.19" - checksum: 888cf5493f781e5fcf54ce4d49e9d7d698f96ea2b2ef67906834bb319a392c667f9ec69f4a10e268d2946d13a9503d2d19b3abaaaf174e3451bfe91fb9d82427 - languageName: node - linkType: hard - -"combined-stream@npm:^1.0.6, combined-stream@npm:~1.0.6": - version: 1.0.8 - resolution: "combined-stream@npm:1.0.8" - dependencies: - delayed-stream: ~1.0.0 - checksum: 49fa4aeb4916567e33ea81d088f6584749fc90c7abec76fd516bf1c5aa5c79f3584b5ba3de6b86d26ddd64bae5329c4c7479343250cfe71c75bb366eae53bb7c - languageName: node - linkType: hard - -"commander@npm:^6.2.1": - version: 6.2.1 - resolution: "commander@npm:6.2.1" - checksum: d7090410c0de6bc5c67d3ca41c41760d6d268f3c799e530aafb73b7437d1826bbf0d2a3edac33f8b57cc9887b4a986dce307fa5557e109be40eadb7c43b21742 - languageName: node - linkType: hard - -"common-tags@npm:^1.8.0": - version: 1.8.2 - resolution: "common-tags@npm:1.8.2" - checksum: 767a6255a84bbc47df49a60ab583053bb29a7d9687066a18500a516188a062c4e4cd52de341f22de0b07062e699b1b8fe3cfa1cb55b241cb9301aeb4f45b4dff - languageName: node - linkType: hard - -"concat-map@npm:0.0.1": - version: 0.0.1 - resolution: "concat-map@npm:0.0.1" - checksum: 902a9f5d8967a3e2faf138d5cb784b9979bad2e6db5357c5b21c568df4ebe62bcb15108af1b2253744844eb964fc023fbd9afbbbb6ddd0bcc204c6fb5b7bf3af - languageName: node - linkType: hard - -"core-util-is@npm:1.0.2": - version: 1.0.2 - resolution: "core-util-is@npm:1.0.2" - checksum: 7a4c925b497a2c91421e25bf76d6d8190f0b2359a9200dbeed136e63b2931d6294d3b1893eda378883ed363cd950f44a12a401384c609839ea616befb7927dab - languageName: node - linkType: hard - -"cross-spawn@npm:^7.0.0": - version: 7.0.3 - resolution: "cross-spawn@npm:7.0.3" - dependencies: - path-key: ^3.1.0 - shebang-command: ^2.0.0 - which: ^2.0.1 - checksum: 671cc7c7288c3a8406f3c69a3ae2fc85555c04169e9d611def9a675635472614f1c0ed0ef80955d5b6d4e724f6ced67f0ad1bb006c2ea643488fcfef994d7f52 - languageName: node - linkType: hard - -"cypress@npm:^12.0.0": - version: 12.17.4 - resolution: "cypress@npm:12.17.4" - dependencies: - "@cypress/request": 2.88.12 - "@cypress/xvfb": ^1.2.4 - "@types/node": ^16.18.39 - "@types/sinonjs__fake-timers": 8.1.1 - "@types/sizzle": ^2.3.2 - arch: ^2.2.0 - blob-util: ^2.0.2 - bluebird: ^3.7.2 - buffer: ^5.6.0 - cachedir: ^2.3.0 - chalk: ^4.1.0 - check-more-types: ^2.24.0 - cli-cursor: ^3.1.0 - cli-table3: ~0.6.1 - commander: ^6.2.1 - common-tags: ^1.8.0 - dayjs: ^1.10.4 - debug: ^4.3.4 - enquirer: ^2.3.6 - eventemitter2: 6.4.7 - execa: 4.1.0 - executable: ^4.1.1 - extract-zip: 2.0.1 - figures: ^3.2.0 - fs-extra: ^9.1.0 - getos: ^3.2.1 - is-ci: ^3.0.0 - is-installed-globally: ~0.4.0 - lazy-ass: ^1.6.0 - listr2: ^3.8.3 - lodash: ^4.17.21 - log-symbols: ^4.0.0 - minimist: ^1.2.8 - ospath: ^1.2.2 - pretty-bytes: ^5.6.0 - process: ^0.11.10 - proxy-from-env: 1.0.0 - request-progress: ^3.0.0 - semver: ^7.5.3 - supports-color: ^8.1.1 - tmp: ~0.2.1 - untildify: ^4.0.0 - yauzl: ^2.10.0 - bin: - cypress: bin/cypress - checksum: c9c79f5493b23e9c8cfb92d45d50ea9d0fae54210dde203bfa794a79436faf60108d826fe9007a7d67fddf7919802ad8f006b7ae56c5c198c75d5bc85bbc851b - languageName: node - linkType: hard - -"dashdash@npm:^1.12.0": - version: 1.14.1 - resolution: "dashdash@npm:1.14.1" - dependencies: - assert-plus: ^1.0.0 - checksum: 3634c249570f7f34e3d34f866c93f866c5b417f0dd616275decae08147dcdf8fccfaa5947380ccfb0473998ea3a8057c0b4cd90c875740ee685d0624b2983598 - languageName: node - linkType: hard - -"dayjs@npm:^1.10.4": - version: 1.11.5 - resolution: "dayjs@npm:1.11.5" - checksum: e3bbaa7b4883b31be4bf75a181f1447fbb19800c29b332852125aab96baeff3ac232dcba8b88c4ea17d3b636c99dac5fb9d1af4bb6ae26615698bbc4a852dffb - languageName: node - linkType: hard - -"debug@npm:^3.1.0": - version: 3.2.7 - resolution: "debug@npm:3.2.7" - dependencies: - ms: ^2.1.1 - checksum: b3d8c5940799914d30314b7c3304a43305fd0715581a919dacb8b3176d024a782062368405b47491516d2091d6462d4d11f2f4974a405048094f8bfebfa3071c - languageName: node - linkType: hard - -"debug@npm:^4.1.1, debug@npm:^4.3.4": - version: 4.3.4 - resolution: "debug@npm:4.3.4" - dependencies: - ms: 2.1.2 - peerDependenciesMeta: - supports-color: - optional: true - checksum: 3dbad3f94ea64f34431a9cbf0bafb61853eda57bff2880036153438f50fb5a84f27683ba0d8e5426bf41a8c6ff03879488120cf5b3a761e77953169c0600a708 - languageName: node - linkType: hard - -"delayed-stream@npm:~1.0.0": - version: 1.0.0 - resolution: "delayed-stream@npm:1.0.0" - checksum: 46fe6e83e2cb1d85ba50bd52803c68be9bd953282fa7096f51fc29edd5d67ff84ff753c51966061e5ba7cb5e47ef6d36a91924eddb7f3f3483b1c560f77a0020 - languageName: node - linkType: hard - -"ecc-jsbn@npm:~0.1.1": - version: 0.1.2 - resolution: "ecc-jsbn@npm:0.1.2" - dependencies: - jsbn: ~0.1.0 - safer-buffer: ^2.1.0 - checksum: 22fef4b6203e5f31d425f5b711eb389e4c6c2723402e389af394f8411b76a488fa414d309d866e2b577ce3e8462d344205545c88a8143cc21752a5172818888a - languageName: node - linkType: hard - -"emoji-regex@npm:^8.0.0": - version: 8.0.0 - resolution: "emoji-regex@npm:8.0.0" - checksum: d4c5c39d5a9868b5fa152f00cada8a936868fd3367f33f71be515ecee4c803132d11b31a6222b2571b1e5f7e13890156a94880345594d0ce7e3c9895f560f192 - languageName: node - linkType: hard - -"end-of-stream@npm:^1.1.0": - version: 1.4.4 - resolution: "end-of-stream@npm:1.4.4" - dependencies: - once: ^1.4.0 - checksum: 530a5a5a1e517e962854a31693dbb5c0b2fc40b46dad2a56a2deec656ca040631124f4795823acc68238147805f8b021abbe221f4afed5ef3c8e8efc2024908b - languageName: node - linkType: hard - -"enquirer@npm:^2.3.6": - version: 2.3.6 - resolution: "enquirer@npm:2.3.6" - dependencies: - ansi-colors: ^4.1.1 - checksum: 1c0911e14a6f8d26721c91e01db06092a5f7675159f0261d69c403396a385afd13dd76825e7678f66daffa930cfaa8d45f506fb35f818a2788463d022af1b884 - languageName: node - linkType: hard - -"escape-string-regexp@npm:^1.0.5": - version: 1.0.5 - resolution: "escape-string-regexp@npm:1.0.5" - checksum: 6092fda75c63b110c706b6a9bfde8a612ad595b628f0bd2147eea1d3406723020810e591effc7db1da91d80a71a737a313567c5abb3813e8d9c71f4aa595b410 - languageName: node - linkType: hard - -"eventemitter2@npm:6.4.7": - version: 6.4.7 - resolution: "eventemitter2@npm:6.4.7" - checksum: 1b36a77e139d6965ebf3a36c01fa00c089ae6b80faa1911e52888f40b3a7057b36a2cc45dcd1ad87cda3798fe7b97a0aabcbb8175a8b96092a23bb7d0f039e66 - languageName: node - linkType: hard - -"execa@npm:4.1.0": - version: 4.1.0 - resolution: "execa@npm:4.1.0" - dependencies: - cross-spawn: ^7.0.0 - get-stream: ^5.0.0 - human-signals: ^1.1.1 - is-stream: ^2.0.0 - merge-stream: ^2.0.0 - npm-run-path: ^4.0.0 - onetime: ^5.1.0 - signal-exit: ^3.0.2 - strip-final-newline: ^2.0.0 - checksum: e30d298934d9c52f90f3847704fd8224e849a081ab2b517bbc02f5f7732c24e56a21f14cb96a08256deffeb2d12b2b7cb7e2b014a12fb36f8d3357e06417ed55 - languageName: node - linkType: hard - -"executable@npm:^4.1.1": - version: 4.1.1 - resolution: "executable@npm:4.1.1" - dependencies: - pify: ^2.2.0 - checksum: f01927ce59bccec804e171bf859a26e362c1f50aa9ebc69f7cafdcce3859d29d4b6267fd47237c18b0a1830614bd3f0ee14b7380d9bad18a4e7af9b5f0b6984f - languageName: node - linkType: hard - -"extend@npm:~3.0.2": - version: 3.0.2 - resolution: "extend@npm:3.0.2" - checksum: a50a8309ca65ea5d426382ff09f33586527882cf532931cb08ca786ea3146c0553310bda688710ff61d7668eba9f96b923fe1420cdf56a2c3eaf30fcab87b515 - languageName: node - linkType: hard - -"extract-zip@npm:2.0.1": - version: 2.0.1 - resolution: "extract-zip@npm:2.0.1" - dependencies: - "@types/yauzl": ^2.9.1 - debug: ^4.1.1 - get-stream: ^5.1.0 - yauzl: ^2.10.0 - dependenciesMeta: - "@types/yauzl": - optional: true - bin: - extract-zip: cli.js - checksum: 8cbda9debdd6d6980819cc69734d874ddd71051c9fe5bde1ef307ebcedfe949ba57b004894b585f758b7c9eeeea0e3d87f2dda89b7d25320459c2c9643ebb635 - languageName: node - linkType: hard - -"extsprintf@npm:1.3.0": - version: 1.3.0 - resolution: "extsprintf@npm:1.3.0" - checksum: cee7a4a1e34cffeeec18559109de92c27517e5641991ec6bab849aa64e3081022903dd53084f2080d0d2530803aa5ee84f1e9de642c365452f9e67be8f958ce2 - languageName: node - linkType: hard - -"extsprintf@npm:^1.2.0": - version: 1.4.1 - resolution: "extsprintf@npm:1.4.1" - checksum: a2f29b241914a8d2bad64363de684821b6b1609d06ae68d5b539e4de6b28659715b5bea94a7265201603713b7027d35399d10b0548f09071c5513e65e8323d33 - languageName: node - linkType: hard - -"fd-slicer@npm:~1.1.0": - version: 1.1.0 - resolution: "fd-slicer@npm:1.1.0" - dependencies: - pend: ~1.2.0 - checksum: c8585fd5713f4476eb8261150900d2cb7f6ff2d87f8feb306ccc8a1122efd152f1783bdb2b8dc891395744583436bfd8081d8e63ece0ec8687eeefea394d4ff2 - languageName: node - linkType: hard - -"figures@npm:^3.2.0": - version: 3.2.0 - resolution: "figures@npm:3.2.0" - dependencies: - escape-string-regexp: ^1.0.5 - checksum: 85a6ad29e9aca80b49b817e7c89ecc4716ff14e3779d9835af554db91bac41c0f289c418923519392a1e582b4d10482ad282021330cd045bb7b80c84152f2a2b - languageName: node - linkType: hard - -"forever-agent@npm:~0.6.1": - version: 0.6.1 - resolution: "forever-agent@npm:0.6.1" - checksum: 766ae6e220f5fe23676bb4c6a99387cec5b7b62ceb99e10923376e27bfea72f3c3aeec2ba5f45f3f7ba65d6616965aa7c20b15002b6860833bb6e394dea546a8 - languageName: node - linkType: hard - -"form-data@npm:~2.3.2": - version: 2.3.3 - resolution: "form-data@npm:2.3.3" - dependencies: - asynckit: ^0.4.0 - combined-stream: ^1.0.6 - mime-types: ^2.1.12 - checksum: 10c1780fa13dbe1ff3100114c2ce1f9307f8be10b14bf16e103815356ff567b6be39d70fc4a40f8990b9660012dc24b0f5e1dde1b6426166eb23a445ba068ca3 - languageName: node - linkType: hard - -"fs-extra@npm:^9.1.0": - version: 9.1.0 - resolution: "fs-extra@npm:9.1.0" - dependencies: - at-least-node: ^1.0.0 - graceful-fs: ^4.2.0 - jsonfile: ^6.0.1 - universalify: ^2.0.0 - checksum: ba71ba32e0faa74ab931b7a0031d1523c66a73e225de7426e275e238e312d07313d2da2d33e34a52aa406c8763ade5712eb3ec9ba4d9edce652bcacdc29e6b20 - languageName: node - linkType: hard - -"fs.realpath@npm:^1.0.0": - version: 1.0.0 - resolution: "fs.realpath@npm:1.0.0" - checksum: 99ddea01a7e75aa276c250a04eedeffe5662bce66c65c07164ad6264f9de18fb21be9433ead460e54cff20e31721c811f4fb5d70591799df5f85dce6d6746fd0 - languageName: node - linkType: hard - -"function-bind@npm:^1.1.1": - version: 1.1.1 - resolution: "function-bind@npm:1.1.1" - checksum: b32fbaebb3f8ec4969f033073b43f5c8befbb58f1a79e12f1d7490358150359ebd92f49e72ff0144f65f2c48ea2a605bff2d07965f548f6474fd8efd95bf361a - languageName: node - linkType: hard - -"get-intrinsic@npm:^1.0.2": - version: 1.2.1 - resolution: "get-intrinsic@npm:1.2.1" - dependencies: - function-bind: ^1.1.1 - has: ^1.0.3 - has-proto: ^1.0.1 - has-symbols: ^1.0.3 - checksum: 5b61d88552c24b0cf6fa2d1b3bc5459d7306f699de060d76442cce49a4721f52b8c560a33ab392cf5575b7810277d54ded9d4d39a1ea61855619ebc005aa7e5f - languageName: node - linkType: hard - -"get-stream@npm:^5.0.0, get-stream@npm:^5.1.0": - version: 5.2.0 - resolution: "get-stream@npm:5.2.0" - dependencies: - pump: ^3.0.0 - checksum: 8bc1a23174a06b2b4ce600df38d6c98d2ef6d84e020c1ddad632ad75bac4e092eeb40e4c09e0761c35fc2dbc5e7fff5dab5e763a383582c4a167dd69a905bd12 - languageName: node - linkType: hard - -"getos@npm:^3.2.1": - version: 3.2.1 - resolution: "getos@npm:3.2.1" - dependencies: - async: ^3.2.0 - checksum: 42fd78a66d47cebd3e09de5566cc0044e034b08f4a000a310dbd89a77b02c65d8f4002554bfa495ea5bdc4fa9d515f5ac785a7cc474ba45383cc697f865eeaf1 - languageName: node - linkType: hard - -"getpass@npm:^0.1.1": - version: 0.1.7 - resolution: "getpass@npm:0.1.7" - dependencies: - assert-plus: ^1.0.0 - checksum: ab18d55661db264e3eac6012c2d3daeafaab7a501c035ae0ccb193c3c23e9849c6e29b6ac762b9c2adae460266f925d55a3a2a3a3c8b94be2f222df94d70c046 - languageName: node - linkType: hard - -"glob@npm:^7.1.3": - version: 7.2.3 - resolution: "glob@npm:7.2.3" - dependencies: - fs.realpath: ^1.0.0 - inflight: ^1.0.4 - inherits: 2 - minimatch: ^3.1.1 - once: ^1.3.0 - path-is-absolute: ^1.0.0 - checksum: 29452e97b38fa704dabb1d1045350fb2467cf0277e155aa9ff7077e90ad81d1ea9d53d3ee63bd37c05b09a065e90f16aec4a65f5b8de401d1dac40bc5605d133 - languageName: node - linkType: hard - -"global-dirs@npm:^3.0.0": - version: 3.0.0 - resolution: "global-dirs@npm:3.0.0" - dependencies: - ini: 2.0.0 - checksum: 953c17cf14bf6ee0e2100ae82a0d779934eed8a3ec5c94a7a4f37c5b3b592c31ea015fb9a15cf32484de13c79f4a814f3015152f3e1d65976cfbe47c1bfe4a88 - languageName: node - linkType: hard - -"graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0": - version: 4.2.10 - resolution: "graceful-fs@npm:4.2.10" - checksum: 3f109d70ae123951905d85032ebeae3c2a5a7a997430df00ea30df0e3a6c60cf6689b109654d6fdacd28810a053348c4d14642da1d075049e6be1ba5216218da - languageName: node - linkType: hard - -"has-flag@npm:^4.0.0": - version: 4.0.0 - resolution: "has-flag@npm:4.0.0" - checksum: 261a1357037ead75e338156b1f9452c016a37dcd3283a972a30d9e4a87441ba372c8b81f818cd0fbcd9c0354b4ae7e18b9e1afa1971164aef6d18c2b6095a8ad - languageName: node - linkType: hard - -"has-proto@npm:^1.0.1": - version: 1.0.1 - resolution: "has-proto@npm:1.0.1" - checksum: febc5b5b531de8022806ad7407935e2135f1cc9e64636c3916c6842bd7995994ca3b29871ecd7954bd35f9e2986c17b3b227880484d22259e2f8e6ce63fd383e - languageName: node - linkType: hard - -"has-symbols@npm:^1.0.3": - version: 1.0.3 - resolution: "has-symbols@npm:1.0.3" - checksum: a054c40c631c0d5741a8285010a0777ea0c068f99ed43e5d6eb12972da223f8af553a455132fdb0801bdcfa0e0f443c0c03a68d8555aa529b3144b446c3f2410 - languageName: node - linkType: hard - -"has@npm:^1.0.3": - version: 1.0.3 - resolution: "has@npm:1.0.3" - dependencies: - function-bind: ^1.1.1 - checksum: b9ad53d53be4af90ce5d1c38331e712522417d017d5ef1ebd0507e07c2fbad8686fffb8e12ddecd4c39ca9b9b47431afbb975b8abf7f3c3b82c98e9aad052792 - languageName: node - linkType: hard - -"http-signature@npm:~1.3.6": - version: 1.3.6 - resolution: "http-signature@npm:1.3.6" - dependencies: - assert-plus: ^1.0.0 - jsprim: ^2.0.2 - sshpk: ^1.14.1 - checksum: 10be2af4764e71fee0281392937050201ee576ac755c543f570d6d87134ce5e858663fe999a7adb3e4e368e1e356d0d7fec6b9542295b875726ff615188e7a0c - languageName: node - linkType: hard - -"human-signals@npm:^1.1.1": - version: 1.1.1 - resolution: "human-signals@npm:1.1.1" - checksum: d587647c9e8ec24e02821b6be7de5a0fc37f591f6c4e319b3054b43fd4c35a70a94c46fc74d8c1a43c47fde157d23acd7421f375e1c1365b09a16835b8300205 - languageName: node - linkType: hard - -"ieee754@npm:^1.1.13": - version: 1.2.1 - resolution: "ieee754@npm:1.2.1" - checksum: 5144c0c9815e54ada181d80a0b810221a253562422e7c6c3a60b1901154184f49326ec239d618c416c1c5945a2e197107aee8d986a3dd836b53dffefd99b5e7e - languageName: node - linkType: hard - -"indent-string@npm:^4.0.0": - version: 4.0.0 - resolution: "indent-string@npm:4.0.0" - checksum: 824cfb9929d031dabf059bebfe08cf3137365e112019086ed3dcff6a0a7b698cb80cf67ccccde0e25b9e2d7527aa6cc1fed1ac490c752162496caba3e6699612 - languageName: node - linkType: hard - -"inflight@npm:^1.0.4": - version: 1.0.6 - resolution: "inflight@npm:1.0.6" - dependencies: - once: ^1.3.0 - wrappy: 1 - checksum: f4f76aa072ce19fae87ce1ef7d221e709afb59d445e05d47fba710e85470923a75de35bfae47da6de1b18afc3ce83d70facf44cfb0aff89f0a3f45c0a0244dfd - languageName: node - linkType: hard - -"inherits@npm:2": - version: 2.0.4 - resolution: "inherits@npm:2.0.4" - checksum: 4a48a733847879d6cf6691860a6b1e3f0f4754176e4d71494c41f3475553768b10f84b5ce1d40fbd0e34e6bfbb864ee35858ad4dd2cf31e02fc4a154b724d7f1 - languageName: node - linkType: hard - -"ini@npm:2.0.0": - version: 2.0.0 - resolution: "ini@npm:2.0.0" - checksum: e7aadc5fb2e4aefc666d74ee2160c073995a4061556b1b5b4241ecb19ad609243b9cceafe91bae49c219519394bbd31512516cb22a3b1ca6e66d869e0447e84e - languageName: node - linkType: hard - -"is-ci@npm:^3.0.0": - version: 3.0.1 - resolution: "is-ci@npm:3.0.1" - dependencies: - ci-info: ^3.2.0 - bin: - is-ci: bin.js - checksum: 192c66dc7826d58f803ecae624860dccf1899fc1f3ac5505284c0a5cf5f889046ffeb958fa651e5725d5705c5bcb14f055b79150ea5fcad7456a9569de60260e - languageName: node - linkType: hard - -"is-fullwidth-code-point@npm:^3.0.0": - version: 3.0.0 - resolution: "is-fullwidth-code-point@npm:3.0.0" - checksum: 44a30c29457c7fb8f00297bce733f0a64cd22eca270f83e58c105e0d015e45c019491a4ab2faef91ab51d4738c670daff901c799f6a700e27f7314029e99e348 - languageName: node - linkType: hard - -"is-installed-globally@npm:~0.4.0": - version: 0.4.0 - resolution: "is-installed-globally@npm:0.4.0" - dependencies: - global-dirs: ^3.0.0 - is-path-inside: ^3.0.2 - checksum: 3359840d5982d22e9b350034237b2cda2a12bac1b48a721912e1ab8e0631dd07d45a2797a120b7b87552759a65ba03e819f1bd63f2d7ab8657ec0b44ee0bf399 - languageName: node - linkType: hard - -"is-path-inside@npm:^3.0.2": - version: 3.0.3 - resolution: "is-path-inside@npm:3.0.3" - checksum: abd50f06186a052b349c15e55b182326f1936c89a78bf6c8f2b707412517c097ce04bc49a0ca221787bc44e1049f51f09a2ffb63d22899051988d3a618ba13e9 - languageName: node - linkType: hard - -"is-stream@npm:^2.0.0": - version: 2.0.1 - resolution: "is-stream@npm:2.0.1" - checksum: b8e05ccdf96ac330ea83c12450304d4a591f9958c11fd17bed240af8d5ffe08aedafa4c0f4cfccd4d28dc9d4d129daca1023633d5c11601a6cbc77521f6fae66 - languageName: node - linkType: hard - -"is-typedarray@npm:~1.0.0": - version: 1.0.0 - resolution: "is-typedarray@npm:1.0.0" - checksum: 3508c6cd0a9ee2e0df2fa2e9baabcdc89e911c7bd5cf64604586697212feec525aa21050e48affb5ffc3df20f0f5d2e2cf79b08caa64e1ccc9578e251763aef7 - languageName: node - linkType: hard - -"is-unicode-supported@npm:^0.1.0": - version: 0.1.0 - resolution: "is-unicode-supported@npm:0.1.0" - checksum: a2aab86ee7712f5c2f999180daaba5f361bdad1efadc9610ff5b8ab5495b86e4f627839d085c6530363c6d6d4ecbde340fb8e54bdb83da4ba8e0865ed5513c52 - languageName: node - linkType: hard - -"isexe@npm:^2.0.0": - version: 2.0.0 - resolution: "isexe@npm:2.0.0" - checksum: 26bf6c5480dda5161c820c5b5c751ae1e766c587b1f951ea3fcfc973bafb7831ae5b54a31a69bd670220e42e99ec154475025a468eae58ea262f813fdc8d1c62 - languageName: node - linkType: hard - -"isstream@npm:~0.1.2": - version: 0.1.2 - resolution: "isstream@npm:0.1.2" - checksum: 1eb2fe63a729f7bdd8a559ab552c69055f4f48eb5c2f03724430587c6f450783c8f1cd936c1c952d0a927925180fcc892ebd5b174236cf1065d4bd5bdb37e963 - languageName: node - linkType: hard - -"jsbn@npm:~0.1.0": - version: 0.1.1 - resolution: "jsbn@npm:0.1.1" - checksum: e5ff29c1b8d965017ef3f9c219dacd6e40ad355c664e277d31246c90545a02e6047018c16c60a00f36d561b3647215c41894f5d869ada6908a2e0ce4200c88f2 - languageName: node - linkType: hard - -"json-schema@npm:0.4.0": - version: 0.4.0 - resolution: "json-schema@npm:0.4.0" - checksum: 66389434c3469e698da0df2e7ac5a3281bcff75e797a5c127db7c5b56270e01ae13d9afa3c03344f76e32e81678337a8c912bdbb75101c62e487dc3778461d72 - languageName: node - linkType: hard - -"json-stringify-safe@npm:~5.0.1": - version: 5.0.1 - resolution: "json-stringify-safe@npm:5.0.1" - checksum: 48ec0adad5280b8a96bb93f4563aa1667fd7a36334f79149abd42446d0989f2ddc58274b479f4819f1f00617957e6344c886c55d05a4e15ebb4ab931e4a6a8ee - languageName: node - linkType: hard - -"jsonfile@npm:^6.0.1": - version: 6.1.0 - resolution: "jsonfile@npm:6.1.0" - dependencies: - graceful-fs: ^4.1.6 - universalify: ^2.0.0 - dependenciesMeta: - graceful-fs: - optional: true - checksum: 7af3b8e1ac8fe7f1eccc6263c6ca14e1966fcbc74b618d3c78a0a2075579487547b94f72b7a1114e844a1e15bb00d440e5d1720bfc4612d790a6f285d5ea8354 - languageName: node - linkType: hard - -"jsprim@npm:^2.0.2": - version: 2.0.2 - resolution: "jsprim@npm:2.0.2" - dependencies: - assert-plus: 1.0.0 - extsprintf: 1.3.0 - json-schema: 0.4.0 - verror: 1.10.0 - checksum: d175f6b1991e160cb0aa39bc857da780e035611986b5492f32395411879fdaf4e513d98677f08f7352dac93a16b66b8361c674b86a3fa406e2e7af6b26321838 - languageName: node - linkType: hard - -"lazy-ass@npm:^1.6.0": - version: 1.6.0 - resolution: "lazy-ass@npm:1.6.0" - checksum: 5a3ebb17915b03452320804466345382a6c25ac782ec4874fecdb2385793896cd459be2f187dc7def8899180c32ee0ab9a1aa7fe52193ac3ff3fe29bb0591729 - languageName: node - linkType: hard - -"listr2@npm:^3.8.3": - version: 3.14.0 - resolution: "listr2@npm:3.14.0" - dependencies: - cli-truncate: ^2.1.0 - colorette: ^2.0.16 - log-update: ^4.0.0 - p-map: ^4.0.0 - rfdc: ^1.3.0 - rxjs: ^7.5.1 - through: ^2.3.8 - wrap-ansi: ^7.0.0 - peerDependencies: - enquirer: ">= 2.3.0 < 3" - peerDependenciesMeta: - enquirer: - optional: true - checksum: fdb8b2d6bdf5df9371ebd5082bee46c6d0ca3d1e5f2b11fbb5a127839855d5f3da9d4968fce94f0a5ec67cac2459766abbb1faeef621065ebb1829b11ef9476d - languageName: node - linkType: hard - -"lodash.once@npm:^4.1.1": - version: 4.1.1 - resolution: "lodash.once@npm:4.1.1" - checksum: d768fa9f9b4e1dc6453be99b753906f58990e0c45e7b2ca5a3b40a33111e5d17f6edf2f768786e2716af90a8e78f8f91431ab8435f761fef00f9b0c256f6d245 - languageName: node - linkType: hard - -"lodash@npm:^4.17.21": - version: 4.17.21 - resolution: "lodash@npm:4.17.21" - checksum: eb835a2e51d381e561e508ce932ea50a8e5a68f4ebdd771ea240d3048244a8d13658acbd502cd4829768c56f2e16bdd4340b9ea141297d472517b83868e677f7 - languageName: node - linkType: hard - -"log-symbols@npm:^4.0.0": - version: 4.1.0 - resolution: "log-symbols@npm:4.1.0" - dependencies: - chalk: ^4.1.0 - is-unicode-supported: ^0.1.0 - checksum: fce1497b3135a0198803f9f07464165e9eb83ed02ceb2273930a6f8a508951178d8cf4f0378e9d28300a2ed2bc49050995d2bd5f53ab716bb15ac84d58c6ef74 - languageName: node - linkType: hard - -"log-update@npm:^4.0.0": - version: 4.0.0 - resolution: "log-update@npm:4.0.0" - dependencies: - ansi-escapes: ^4.3.0 - cli-cursor: ^3.1.0 - slice-ansi: ^4.0.0 - wrap-ansi: ^6.2.0 - checksum: ae2f85bbabc1906034154fb7d4c4477c79b3e703d22d78adee8b3862fa913942772e7fa11713e3d96fb46de4e3cabefbf5d0a544344f03b58d3c4bff52aa9eb2 - languageName: node - linkType: hard - -"lru-cache@npm:^6.0.0": - version: 6.0.0 - resolution: "lru-cache@npm:6.0.0" - dependencies: - yallist: ^4.0.0 - checksum: f97f499f898f23e4585742138a22f22526254fdba6d75d41a1c2526b3b6cc5747ef59c5612ba7375f42aca4f8461950e925ba08c991ead0651b4918b7c978297 - languageName: node - linkType: hard - -"merge-stream@npm:^2.0.0": - version: 2.0.0 - resolution: "merge-stream@npm:2.0.0" - checksum: 6fa4dcc8d86629705cea944a4b88ef4cb0e07656ebf223fa287443256414283dd25d91c1cd84c77987f2aec5927af1a9db6085757cb43d90eb170ebf4b47f4f4 - languageName: node - linkType: hard - -"mime-db@npm:1.52.0": - version: 1.52.0 - resolution: "mime-db@npm:1.52.0" - checksum: 0d99a03585f8b39d68182803b12ac601d9c01abfa28ec56204fa330bc9f3d1c5e14beb049bafadb3dbdf646dfb94b87e24d4ec7b31b7279ef906a8ea9b6a513f - languageName: node - linkType: hard - -"mime-types@npm:^2.1.12, mime-types@npm:~2.1.19": - version: 2.1.35 - resolution: "mime-types@npm:2.1.35" - dependencies: - mime-db: 1.52.0 - checksum: 89a5b7f1def9f3af5dad6496c5ed50191ae4331cc5389d7c521c8ad28d5fdad2d06fd81baf38fed813dc4e46bb55c8145bb0ff406330818c9cf712fb2e9b3836 - languageName: node - linkType: hard - -"mimic-fn@npm:^2.1.0": - version: 2.1.0 - resolution: "mimic-fn@npm:2.1.0" - checksum: d2421a3444848ce7f84bd49115ddacff29c15745db73f54041edc906c14b131a38d05298dae3081667627a59b2eb1ca4b436ff2e1b80f69679522410418b478a - languageName: node - linkType: hard - -"minimatch@npm:^3.1.1": - version: 3.1.2 - resolution: "minimatch@npm:3.1.2" - dependencies: - brace-expansion: ^1.1.7 - checksum: c154e566406683e7bcb746e000b84d74465b3a832c45d59912b9b55cd50dee66e5c4b1e5566dba26154040e51672f9aa450a9aef0c97cfc7336b78b7afb9540a - languageName: node - linkType: hard - -"minimist@npm:^1.2.8": - version: 1.2.8 - resolution: "minimist@npm:1.2.8" - checksum: 75a6d645fb122dad29c06a7597bddea977258957ed88d7a6df59b5cd3fe4a527e253e9bbf2e783e4b73657f9098b96a5fe96ab8a113655d4109108577ecf85b0 - languageName: node - linkType: hard - -"ms@npm:2.1.2": - version: 2.1.2 - resolution: "ms@npm:2.1.2" - checksum: 673cdb2c3133eb050c745908d8ce632ed2c02d85640e2edb3ace856a2266a813b30c613569bf3354fdf4ea7d1a1494add3bfa95e2713baa27d0c2c71fc44f58f - languageName: node - linkType: hard - -"ms@npm:^2.1.1": - version: 2.1.3 - resolution: "ms@npm:2.1.3" - checksum: aa92de608021b242401676e35cfa5aa42dd70cbdc082b916da7fb925c542173e36bce97ea3e804923fe92c0ad991434e4a38327e15a1b5b5f945d66df615ae6d - languageName: node - linkType: hard - -"npm-run-path@npm:^4.0.0": - version: 4.0.1 - resolution: "npm-run-path@npm:4.0.1" - dependencies: - path-key: ^3.0.0 - checksum: 5374c0cea4b0bbfdfae62da7bbdf1e1558d338335f4cacf2515c282ff358ff27b2ecb91ffa5330a8b14390ac66a1e146e10700440c1ab868208430f56b5f4d23 - languageName: node - linkType: hard - -"object-inspect@npm:^1.9.0": - version: 1.12.3 - resolution: "object-inspect@npm:1.12.3" - checksum: dabfd824d97a5f407e6d5d24810d888859f6be394d8b733a77442b277e0808860555176719c5905e765e3743a7cada6b8b0a3b85e5331c530fd418cc8ae991db - languageName: node - linkType: hard - -"once@npm:^1.3.0, once@npm:^1.3.1, once@npm:^1.4.0": - version: 1.4.0 - resolution: "once@npm:1.4.0" - dependencies: - wrappy: 1 - checksum: cd0a88501333edd640d95f0d2700fbde6bff20b3d4d9bdc521bdd31af0656b5706570d6c6afe532045a20bb8dc0849f8332d6f2a416e0ba6d3d3b98806c7db68 - languageName: node - linkType: hard - -"onetime@npm:^5.1.0": - version: 5.1.2 - resolution: "onetime@npm:5.1.2" - dependencies: - mimic-fn: ^2.1.0 - checksum: 2478859ef817fc5d4e9c2f9e5728512ddd1dbc9fb7829ad263765bb6d3b91ce699d6e2332eef6b7dff183c2f490bd3349f1666427eaba4469fba0ac38dfd0d34 - languageName: node - linkType: hard - -"ospath@npm:^1.2.2": - version: 1.2.2 - resolution: "ospath@npm:1.2.2" - checksum: 505f48a4f4f1c557d6c656ec985707726e3714721680139be037613e903aa8c8fa4ddd8d1342006f9b2dc0065e6e20f8b7bea2ee05354f31257044790367b347 - languageName: node - linkType: hard - -"p-map@npm:^4.0.0": - version: 4.0.0 - resolution: "p-map@npm:4.0.0" - dependencies: - aggregate-error: ^3.0.0 - checksum: cb0ab21ec0f32ddffd31dfc250e3afa61e103ef43d957cc45497afe37513634589316de4eb88abdfd969fe6410c22c0b93ab24328833b8eb1ccc087fc0442a1c - languageName: node - linkType: hard - -"path-is-absolute@npm:^1.0.0": - version: 1.0.1 - resolution: "path-is-absolute@npm:1.0.1" - checksum: 060840f92cf8effa293bcc1bea81281bd7d363731d214cbe5c227df207c34cd727430f70c6037b5159c8a870b9157cba65e775446b0ab06fd5ecc7e54615a3b8 - languageName: node - linkType: hard - -"path-key@npm:^3.0.0, path-key@npm:^3.1.0": - version: 3.1.1 - resolution: "path-key@npm:3.1.1" - checksum: 55cd7a9dd4b343412a8386a743f9c746ef196e57c823d90ca3ab917f90ab9f13dd0ded27252ba49dbdfcab2b091d998bc446f6220cd3cea65db407502a740020 - languageName: node - linkType: hard - -"pend@npm:~1.2.0": - version: 1.2.0 - resolution: "pend@npm:1.2.0" - checksum: 6c72f5243303d9c60bd98e6446ba7d30ae29e3d56fdb6fae8767e8ba6386f33ee284c97efe3230a0d0217e2b1723b8ab490b1bbf34fcbb2180dbc8a9de47850d - languageName: node - linkType: hard - -"performance-now@npm:^2.1.0": - version: 2.1.0 - resolution: "performance-now@npm:2.1.0" - checksum: 534e641aa8f7cba160f0afec0599b6cecefbb516a2e837b512be0adbe6c1da5550e89c78059c7fabc5c9ffdf6627edabe23eb7c518c4500067a898fa65c2b550 - languageName: node - linkType: hard - -"pify@npm:^2.2.0": - version: 2.3.0 - resolution: "pify@npm:2.3.0" - checksum: 9503aaeaf4577acc58642ad1d25c45c6d90288596238fb68f82811c08104c800e5a7870398e9f015d82b44ecbcbef3dc3d4251a1cbb582f6e5959fe09884b2ba - languageName: node - linkType: hard - -"pretty-bytes@npm:^5.6.0": - version: 5.6.0 - resolution: "pretty-bytes@npm:5.6.0" - checksum: 9c082500d1e93434b5b291bd651662936b8bd6204ec9fa17d563116a192d6d86b98f6d328526b4e8d783c07d5499e2614a807520249692da9ec81564b2f439cd - languageName: node - linkType: hard - -"process@npm:^0.11.10": - version: 0.11.10 - resolution: "process@npm:0.11.10" - checksum: bfcce49814f7d172a6e6a14d5fa3ac92cc3d0c3b9feb1279774708a719e19acd673995226351a082a9ae99978254e320ccda4240ddc474ba31a76c79491ca7c3 - languageName: node - linkType: hard - -"proxy-from-env@npm:1.0.0": - version: 1.0.0 - resolution: "proxy-from-env@npm:1.0.0" - checksum: 292e28d1de0c315958d71d8315eb546dd3cd8c8cbc2dab7c54eeb9f5c17f421771964ad0b5e1f77011bab2305bdae42e1757ce33bdb1ccc3e87732322a8efcf1 - languageName: node - linkType: hard - -"psl@npm:^1.1.33": - version: 1.9.0 - resolution: "psl@npm:1.9.0" - checksum: 20c4277f640c93d393130673f392618e9a8044c6c7bf61c53917a0fddb4952790f5f362c6c730a9c32b124813e173733f9895add8d26f566ed0ea0654b2e711d - languageName: node - linkType: hard - -"pump@npm:^3.0.0": - version: 3.0.0 - resolution: "pump@npm:3.0.0" - dependencies: - end-of-stream: ^1.1.0 - once: ^1.3.1 - checksum: e42e9229fba14732593a718b04cb5e1cfef8254544870997e0ecd9732b189a48e1256e4e5478148ecb47c8511dca2b09eae56b4d0aad8009e6fac8072923cfc9 - languageName: node - linkType: hard - -"punycode@npm:^2.1.1": - version: 2.1.1 - resolution: "punycode@npm:2.1.1" - checksum: 823bf443c6dd14f669984dea25757b37993f67e8d94698996064035edd43bed8a5a17a9f12e439c2b35df1078c6bec05a6c86e336209eb1061e8025c481168e8 - languageName: node - linkType: hard - -"qs@npm:~6.10.3": - version: 6.10.4 - resolution: "qs@npm:6.10.4" - dependencies: - side-channel: ^1.0.4 - checksum: 31e4fedd759d01eae52dde6692abab175f9af3e639993c5caaa513a2a3607b34d8058d3ae52ceeccf37c3025f22ed5e90e9ddd6c2537e19c0562ddd10dc5b1eb - languageName: node - linkType: hard - -"querystringify@npm:^2.1.1": - version: 2.2.0 - resolution: "querystringify@npm:2.2.0" - checksum: 5641ea231bad7ef6d64d9998faca95611ed4b11c2591a8cae741e178a974f6a8e0ebde008475259abe1621cb15e692404e6b6626e927f7b849d5c09392604b15 - languageName: node - linkType: hard - -"request-progress@npm:^3.0.0": - version: 3.0.0 - resolution: "request-progress@npm:3.0.0" - dependencies: - throttleit: ^1.0.0 - checksum: 6ea1761dcc8a8b7b5894afd478c0286aa31bd69438d7050294bd4fd0d0b3e09b5cde417d38deef9c49809039c337d8744e4bb49d8632b0c3e4ffa5e8a687e0fd - languageName: node - linkType: hard - -"requires-port@npm:^1.0.0": - version: 1.0.0 - resolution: "requires-port@npm:1.0.0" - checksum: eee0e303adffb69be55d1a214e415cf42b7441ae858c76dfc5353148644f6fd6e698926fc4643f510d5c126d12a705e7c8ed7e38061113bdf37547ab356797ff - languageName: node - linkType: hard - -"restore-cursor@npm:^3.1.0": - version: 3.1.0 - resolution: "restore-cursor@npm:3.1.0" - dependencies: - onetime: ^5.1.0 - signal-exit: ^3.0.2 - checksum: f877dd8741796b909f2a82454ec111afb84eb45890eb49ac947d87991379406b3b83ff9673a46012fca0d7844bb989f45cc5b788254cf1a39b6b5a9659de0630 - languageName: node - linkType: hard - -"rfdc@npm:^1.3.0": - version: 1.3.0 - resolution: "rfdc@npm:1.3.0" - checksum: fb2ba8512e43519983b4c61bd3fa77c0f410eff6bae68b08614437bc3f35f91362215f7b4a73cbda6f67330b5746ce07db5dd9850ad3edc91271ad6deea0df32 - languageName: node - linkType: hard - -"rimraf@npm:^3.0.0": - version: 3.0.2 - resolution: "rimraf@npm:3.0.2" - dependencies: - glob: ^7.1.3 - bin: - rimraf: bin.js - checksum: 87f4164e396f0171b0a3386cc1877a817f572148ee13a7e113b238e48e8a9f2f31d009a92ec38a591ff1567d9662c6b67fd8818a2dbbaed74bc26a87a2a4a9a0 - languageName: node - linkType: hard - -"rxjs@npm:^7.5.1": - version: 7.5.6 - resolution: "rxjs@npm:7.5.6" - dependencies: - tslib: ^2.1.0 - checksum: fc05f01364a74dac57490fb3e07ea63b422af04017fae1db641a009073f902ef69f285c5daac31359620dc8d9aee7d81e42b370ca2a8573d1feae0b04329383b - languageName: node - linkType: hard - -"safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.2": - version: 5.2.1 - resolution: "safe-buffer@npm:5.2.1" - checksum: b99c4b41fdd67a6aaf280fcd05e9ffb0813654894223afb78a31f14a19ad220bba8aba1cb14eddce1fcfb037155fe6de4e861784eb434f7d11ed58d1e70dd491 - languageName: node - linkType: hard - -"safer-buffer@npm:^2.0.2, safer-buffer@npm:^2.1.0, safer-buffer@npm:~2.1.0": - version: 2.1.2 - resolution: "safer-buffer@npm:2.1.2" - checksum: cab8f25ae6f1434abee8d80023d7e72b598cf1327164ddab31003c51215526801e40b66c5e65d658a0af1e9d6478cadcb4c745f4bd6751f97d8644786c0978b0 - languageName: node - linkType: hard - -"semver@npm:^7.5.3": - version: 7.5.4 - resolution: "semver@npm:7.5.4" - dependencies: - lru-cache: ^6.0.0 - bin: - semver: bin/semver.js - checksum: 12d8ad952fa353b0995bf180cdac205a4068b759a140e5d3c608317098b3575ac2f1e09182206bf2eb26120e1c0ed8fb92c48c592f6099680de56bb071423ca3 - languageName: node - linkType: hard - -"shebang-command@npm:^2.0.0": - version: 2.0.0 - resolution: "shebang-command@npm:2.0.0" - dependencies: - shebang-regex: ^3.0.0 - checksum: 6b52fe87271c12968f6a054e60f6bde5f0f3d2db483a1e5c3e12d657c488a15474121a1d55cd958f6df026a54374ec38a4a963988c213b7570e1d51575cea7fa - languageName: node - linkType: hard - -"shebang-regex@npm:^3.0.0": - version: 3.0.0 - resolution: "shebang-regex@npm:3.0.0" - checksum: 1a2bcae50de99034fcd92ad4212d8e01eedf52c7ec7830eedcf886622804fe36884278f2be8be0ea5fde3fd1c23911643a4e0f726c8685b61871c8908af01222 - languageName: node - linkType: hard - -"side-channel@npm:^1.0.4": - version: 1.0.4 - resolution: "side-channel@npm:1.0.4" - dependencies: - call-bind: ^1.0.0 - get-intrinsic: ^1.0.2 - object-inspect: ^1.9.0 - checksum: 351e41b947079c10bd0858364f32bb3a7379514c399edb64ab3dce683933483fc63fb5e4efe0a15a2e8a7e3c436b6a91736ddb8d8c6591b0460a24bb4a1ee245 - languageName: node - linkType: hard - -"signal-exit@npm:^3.0.2": - version: 3.0.7 - resolution: "signal-exit@npm:3.0.7" - checksum: a2f098f247adc367dffc27845853e9959b9e88b01cb301658cfe4194352d8d2bb32e18467c786a7fe15f1d44b233ea35633d076d5e737870b7139949d1ab6318 - languageName: node - linkType: hard - -"slice-ansi@npm:^3.0.0": - version: 3.0.0 - resolution: "slice-ansi@npm:3.0.0" - dependencies: - ansi-styles: ^4.0.0 - astral-regex: ^2.0.0 - is-fullwidth-code-point: ^3.0.0 - checksum: 5ec6d022d12e016347e9e3e98a7eb2a592213a43a65f1b61b74d2c78288da0aded781f665807a9f3876b9daa9ad94f64f77d7633a0458876c3a4fdc4eb223f24 - languageName: node - linkType: hard - -"slice-ansi@npm:^4.0.0": - version: 4.0.0 - resolution: "slice-ansi@npm:4.0.0" - dependencies: - ansi-styles: ^4.0.0 - astral-regex: ^2.0.0 - is-fullwidth-code-point: ^3.0.0 - checksum: 4a82d7f085b0e1b070e004941ada3c40d3818563ac44766cca4ceadd2080427d337554f9f99a13aaeb3b4a94d9964d9466c807b3d7b7541d1ec37ee32d308756 - languageName: node - linkType: hard - -"sshpk@npm:^1.14.1": - version: 1.17.0 - resolution: "sshpk@npm:1.17.0" - dependencies: - asn1: ~0.2.3 - assert-plus: ^1.0.0 - bcrypt-pbkdf: ^1.0.0 - dashdash: ^1.12.0 - ecc-jsbn: ~0.1.1 - getpass: ^0.1.1 - jsbn: ~0.1.0 - safer-buffer: ^2.0.2 - tweetnacl: ~0.14.0 - bin: - sshpk-conv: bin/sshpk-conv - sshpk-sign: bin/sshpk-sign - sshpk-verify: bin/sshpk-verify - checksum: ba109f65c8e6c35133b8e6ed5576abeff8aa8d614824b7275ec3ca308f081fef483607c28d97780c1e235818b0f93ed8c8b56d0a5968d5a23fd6af57718c7597 - languageName: node - linkType: hard - -"string-width@npm:^4.1.0, string-width@npm:^4.2.0": - version: 4.2.3 - resolution: "string-width@npm:4.2.3" - dependencies: - emoji-regex: ^8.0.0 - is-fullwidth-code-point: ^3.0.0 - strip-ansi: ^6.0.1 - checksum: e52c10dc3fbfcd6c3a15f159f54a90024241d0f149cf8aed2982a2d801d2e64df0bf1dc351cf8e95c3319323f9f220c16e740b06faecd53e2462df1d2b5443fb - languageName: node - linkType: hard - -"strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": - version: 6.0.1 - resolution: "strip-ansi@npm:6.0.1" - dependencies: - ansi-regex: ^5.0.1 - checksum: f3cd25890aef3ba6e1a74e20896c21a46f482e93df4a06567cebf2b57edabb15133f1f94e57434e0a958d61186087b1008e89c94875d019910a213181a14fc8c - languageName: node - linkType: hard - -"strip-final-newline@npm:^2.0.0": - version: 2.0.0 - resolution: "strip-final-newline@npm:2.0.0" - checksum: 69412b5e25731e1938184b5d489c32e340605bb611d6140344abc3421b7f3c6f9984b21dff296dfcf056681b82caa3bb4cc996a965ce37bcfad663e92eae9c64 - languageName: node - linkType: hard - -"supports-color@npm:^7.1.0": - version: 7.2.0 - resolution: "supports-color@npm:7.2.0" - dependencies: - has-flag: ^4.0.0 - checksum: 3dda818de06ebbe5b9653e07842d9479f3555ebc77e9a0280caf5a14fb877ffee9ed57007c3b78f5a6324b8dbeec648d9e97a24e2ed9fdb81ddc69ea07100f4a - languageName: node - linkType: hard - -"supports-color@npm:^8.1.1": - version: 8.1.1 - resolution: "supports-color@npm:8.1.1" - dependencies: - has-flag: ^4.0.0 - checksum: c052193a7e43c6cdc741eb7f378df605636e01ad434badf7324f17fb60c69a880d8d8fcdcb562cf94c2350e57b937d7425ab5b8326c67c2adc48f7c87c1db406 - languageName: node - linkType: hard - -"throttleit@npm:^1.0.0": - version: 1.0.0 - resolution: "throttleit@npm:1.0.0" - checksum: 1b2db4d2454202d589e8236c07a69d2fab838876d370030ebea237c34c0a7d1d9cf11c29f994531ebb00efd31e9728291042b7754f2798a8352ec4463455b659 - languageName: node - linkType: hard - -"through@npm:^2.3.8": - version: 2.3.8 - resolution: "through@npm:2.3.8" - checksum: a38c3e059853c494af95d50c072b83f8b676a9ba2818dcc5b108ef252230735c54e0185437618596c790bbba8fcdaef5b290405981ffa09dce67b1f1bf190cbd - languageName: node - linkType: hard - -"tmp@npm:~0.2.1": - version: 0.2.1 - resolution: "tmp@npm:0.2.1" - dependencies: - rimraf: ^3.0.0 - checksum: 8b1214654182575124498c87ca986ac53dc76ff36e8f0e0b67139a8d221eaecfdec108c0e6ec54d76f49f1f72ab9325500b246f562b926f85bcdfca8bf35df9e - languageName: node - linkType: hard - -"tough-cookie@npm:^4.1.3": - version: 4.1.3 - resolution: "tough-cookie@npm:4.1.3" - dependencies: - psl: ^1.1.33 - punycode: ^2.1.1 - universalify: ^0.2.0 - url-parse: ^1.5.3 - checksum: c9226afff36492a52118432611af083d1d8493a53ff41ec4ea48e5b583aec744b989e4280bcf476c910ec1525a89a4a0f1cae81c08b18fb2ec3a9b3a72b91dcc - languageName: node - linkType: hard - -"tslib@npm:^2.1.0": - version: 2.4.0 - resolution: "tslib@npm:2.4.0" - checksum: 8c4aa6a3c5a754bf76aefc38026134180c053b7bd2f81338cb5e5ebf96fefa0f417bff221592bf801077f5bf990562f6264fecbc42cd3309b33872cb6fc3b113 - languageName: node - linkType: hard - -"tunnel-agent@npm:^0.6.0": - version: 0.6.0 - resolution: "tunnel-agent@npm:0.6.0" - dependencies: - safe-buffer: ^5.0.1 - checksum: 05f6510358f8afc62a057b8b692f05d70c1782b70db86d6a1e0d5e28a32389e52fa6e7707b6c5ecccacc031462e4bc35af85ecfe4bbc341767917b7cf6965711 - languageName: node - linkType: hard - -"tweetnacl@npm:^0.14.3, tweetnacl@npm:~0.14.0": - version: 0.14.5 - resolution: "tweetnacl@npm:0.14.5" - checksum: 6061daba1724f59473d99a7bb82e13f211cdf6e31315510ae9656fefd4779851cb927adad90f3b488c8ed77c106adc0421ea8055f6f976ff21b27c5c4e918487 - languageName: node - linkType: hard - -"type-fest@npm:^0.21.3": - version: 0.21.3 - resolution: "type-fest@npm:0.21.3" - checksum: e6b32a3b3877f04339bae01c193b273c62ba7bfc9e325b8703c4ee1b32dc8fe4ef5dfa54bf78265e069f7667d058e360ae0f37be5af9f153b22382cd55a9afe0 - languageName: node - linkType: hard - -"typescript@npm:~5.0.0": - version: 5.0.4 - resolution: "typescript@npm:5.0.4" - bin: - tsc: bin/tsc - tsserver: bin/tsserver - checksum: 82b94da3f4604a8946da585f7d6c3025fff8410779e5bde2855ab130d05e4fd08938b9e593b6ebed165bda6ad9292b230984f10952cf82f0a0ca07bbeaa08172 - languageName: node - linkType: hard - -"typescript@patch:typescript@~5.0.0#~builtin": - version: 5.0.4 - resolution: "typescript@patch:typescript@npm%3A5.0.4#~builtin::version=5.0.4&hash=a1c5e5" - bin: - tsc: bin/tsc - tsserver: bin/tsserver - checksum: 6a1fe9a77bb9c5176ead919cc4a1499ee63e46b4e05bf667079f11bf3a8f7887f135aa72460a4c3b016e6e6bb65a822cb8689a6d86cbfe92d22cc9f501f09213 - languageName: node - linkType: hard - -"universalify@npm:^0.2.0": - version: 0.2.0 - resolution: "universalify@npm:0.2.0" - checksum: e86134cb12919d177c2353196a4cc09981524ee87abf621f7bc8d249dbbbebaec5e7d1314b96061497981350df786e4c5128dbf442eba104d6e765bc260678b5 - languageName: node - linkType: hard - -"universalify@npm:^2.0.0": - version: 2.0.0 - resolution: "universalify@npm:2.0.0" - checksum: 2406a4edf4a8830aa6813278bab1f953a8e40f2f63a37873ffa9a3bc8f9745d06cc8e88f3572cb899b7e509013f7f6fcc3e37e8a6d914167a5381d8440518c44 - languageName: node - linkType: hard - -"untildify@npm:^4.0.0": - version: 4.0.0 - resolution: "untildify@npm:4.0.0" - checksum: 39ced9c418a74f73f0a56e1ba4634b4d959422dff61f4c72a8e39f60b99380c1b45ed776fbaa0a4101b157e4310d873ad7d114e8534ca02609b4916bb4187fb9 - languageName: node - linkType: hard - -"url-parse@npm:^1.5.3": - version: 1.5.10 - resolution: "url-parse@npm:1.5.10" - dependencies: - querystringify: ^2.1.1 - requires-port: ^1.0.0 - checksum: fbdba6b1d83336aca2216bbdc38ba658d9cfb8fc7f665eb8b17852de638ff7d1a162c198a8e4ed66001ddbf6c9888d41e4798912c62b4fd777a31657989f7bdf - languageName: node - linkType: hard - -"uuid@npm:^8.3.2": - version: 8.3.2 - resolution: "uuid@npm:8.3.2" - bin: - uuid: dist/bin/uuid - checksum: 5575a8a75c13120e2f10e6ddc801b2c7ed7d8f3c8ac22c7ed0c7b2ba6383ec0abda88c905085d630e251719e0777045ae3236f04c812184b7c765f63a70e58df - languageName: node - linkType: hard - -"verror@npm:1.10.0": - version: 1.10.0 - resolution: "verror@npm:1.10.0" - dependencies: - assert-plus: ^1.0.0 - core-util-is: 1.0.2 - extsprintf: ^1.2.0 - checksum: c431df0bedf2088b227a4e051e0ff4ca54df2c114096b0c01e1cbaadb021c30a04d7dd5b41ab277bcd51246ca135bf931d4c4c796ecae7a4fef6d744ecef36ea - languageName: node - linkType: hard - -"which@npm:^2.0.1": - version: 2.0.2 - resolution: "which@npm:2.0.2" - dependencies: - isexe: ^2.0.0 - bin: - node-which: ./bin/node-which - checksum: 1a5c563d3c1b52d5f893c8b61afe11abc3bab4afac492e8da5bde69d550de701cf9806235f20a47b5c8fa8a1d6a9135841de2596535e998027a54589000e66d1 - languageName: node - linkType: hard - -"wrap-ansi@npm:^6.2.0": - version: 6.2.0 - resolution: "wrap-ansi@npm:6.2.0" - dependencies: - ansi-styles: ^4.0.0 - string-width: ^4.1.0 - strip-ansi: ^6.0.0 - checksum: 6cd96a410161ff617b63581a08376f0cb9162375adeb7956e10c8cd397821f7eb2a6de24eb22a0b28401300bf228c86e50617cd568209b5f6775b93c97d2fe3a - languageName: node - linkType: hard - -"wrap-ansi@npm:^7.0.0": - version: 7.0.0 - resolution: "wrap-ansi@npm:7.0.0" - dependencies: - ansi-styles: ^4.0.0 - string-width: ^4.1.0 - strip-ansi: ^6.0.0 - checksum: a790b846fd4505de962ba728a21aaeda189b8ee1c7568ca5e817d85930e06ef8d1689d49dbf0e881e8ef84436af3a88bc49115c2e2788d841ff1b8b5b51a608b - languageName: node - linkType: hard - -"wrappy@npm:1": - version: 1.0.2 - resolution: "wrappy@npm:1.0.2" - checksum: 159da4805f7e84a3d003d8841557196034155008f817172d4e986bd591f74aa82aa7db55929a54222309e01079a65a92a9e6414da5a6aa4b01ee44a511ac3ee5 - languageName: node - linkType: hard - -"yallist@npm:^4.0.0": - version: 4.0.0 - resolution: "yallist@npm:4.0.0" - checksum: 343617202af32df2a15a3be36a5a8c0c8545208f3d3dfbc6bb7c3e3b7e8c6f8e7485432e4f3b88da3031a6e20afa7c711eded32ddfb122896ac5d914e75848d5 - languageName: node - linkType: hard - -"yauzl@npm:^2.10.0": - version: 2.10.0 - resolution: "yauzl@npm:2.10.0" - dependencies: - buffer-crc32: ~0.2.3 - fd-slicer: ~1.1.0 - checksum: 7f21fe0bbad6e2cb130044a5d1d0d5a0e5bf3d8d4f8c4e6ee12163ce798fee3de7388d22a7a0907f563ac5f9d40f8699a223d3d5c1718da90b0156da6904022b - languageName: node - linkType: hard diff --git a/packages/app-next/package.json b/packages/app-next/package.json index fe052773df..453859805a 100644 --- a/packages/app-next/package.json +++ b/packages/app-next/package.json @@ -99,7 +99,6 @@ }, "devDependencies": { "@backstage/test-utils": "workspace:^", - "@testing-library/cypress": "^9.0.0", "@testing-library/dom": "^8.0.0", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", @@ -108,21 +107,14 @@ "@types/react": "*", "@types/react-dom": "*", "@types/zen-observable": "^0.8.0", - "cross-env": "^7.0.0", - "cypress": "^12.0.0", - "eslint-plugin-cypress": "^2.10.3", - "start-server-and-test": "^1.10.11" + "cross-env": "^7.0.0" }, "scripts": { "start": "backstage-cli package start --config ../../app-config.yaml --config app-config.yaml", "build": "backstage-cli package build", "clean": "backstage-cli package clean", "test": "backstage-cli package test", - "lint": "backstage-cli package lint", - "test:e2e": "start-server-and-test start http://localhost:3000 cy:dev", - "test:e2e:ci": "start-server-and-test start http://localhost:3000 cy:run", - "cy:dev": "cypress open", - "cy:run": "cypress run" + "lint": "backstage-cli package lint" }, "browserslist": { "production": [ diff --git a/packages/app/cypress.json b/packages/app/cypress.json deleted file mode 100644 index 6ae01d9c2a..0000000000 --- a/packages/app/cypress.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "baseUrl": "http://localhost:3000", - "fixturesFolder": false, - "pluginsFile": false -} diff --git a/packages/app/cypress/.eslintrc.json b/packages/app/cypress/.eslintrc.json deleted file mode 100644 index b903ff250a..0000000000 --- a/packages/app/cypress/.eslintrc.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "plugins": ["cypress"], - "extends": ["plugin:cypress/recommended"], - "rules": { - "jest/expect-expect": [ - "error", - { - "assertFunctionNames": ["expect", "cy.contains", "cy.**.should"] - } - ] - } -} diff --git a/packages/app/cypress/integration/app.js b/packages/app/cypress/integration/app.js deleted file mode 100644 index 6371bcc4f8..0000000000 --- a/packages/app/cypress/integration/app.js +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2020 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. - */ - -describe('App', () => { - it('should render the welcome page', () => { - cy.visit('/'); - cy.contains('Welcome to Backstage'); - cy.contains('Getting Started'); - cy.contains('Quick Links'); - cy.contains('APIs'); - }); - - it('should display support info when clicking the button', () => { - cy.visit('/'); - // eslint-disable-next-line testing-library/await-async-query - cy.findByTestId('support-button').click({ force: true }); - cy.contains('#backstage'); - }); - - it('should display error message when triggering it', () => { - cy.visit('/'); - // eslint-disable-next-line testing-library/await-async-query - cy.findByTestId('error-button').click({ force: true }); - cy.contains('Error: Oh no!'); - // eslint-disable-next-line testing-library/await-async-query - cy.findByTestId('error-button-close').click({ force: true }); - }); - - it('should be able to login and logout', () => { - const name = 'test-name'; - Cypress.on('window:before:load', win => { - win.fetch = cy.stub().resolves({ - status: 200, - json: () => ({ username: 'test name', token: 'token', name }), - }); - }); - - cy.visit('/'); - cy.get('a[href="/login"]').click({ force: true }); - cy.url().should('include', '/login'); - cy.contains('Welcome, guest!'); - cy.contains('Username') - .get('input[name=github-username-tf]') - .type(name, { force: true }); - cy.contains('Token') - .get('input[name=github-auth-tf]') - .type('password', { force: true }); - // eslint-disable-next-line testing-library/await-async-query - cy.findByTestId('github-auth-button').click({ force: true }); - cy.contains(`Welcome, ${name}!`); - cy.contains('Logout').click({ force: true }); - cy.contains('Welcome, guest!'); - }); -}); diff --git a/packages/app/cypress/integration/components/search/SearchPage.js b/packages/app/cypress/integration/components/search/SearchPage.js deleted file mode 100644 index 11f31cfed3..0000000000 --- a/packages/app/cypress/integration/components/search/SearchPage.js +++ /dev/null @@ -1,121 +0,0 @@ -/* - * 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. - */ - -const API_ENDPOINT = 'http://localhost:7007/api/search/query'; - -describe('SearchPage', () => { - describe('Given a search context with a term, results, and filter values', () => { - it('The results are rendered as expected', () => { - const results = [ - { - type: 'software-catalog', - document: { - title: 'backstage', - text: 'Backstage system documentation', - location: '/result/location/path', - }, - }, - ]; - - cy.enterAsGuest(); - cy.visit('/search-next', { - onBeforeLoad(win) { - cy.stub(win, 'fetch') - .withArgs(`${API_ENDPOINT}?term=`) - .resolves({ - ok: true, - json: () => ({ results }), - }); - }, - }); - cy.contains('Search'); - - cy.contains(results[0].document.title); - cy.contains(results[0].document.text); - cy.get(`a[href="${results[0].document.location}"]`).should('be.visible'); - }); - - it('The filters are rendered as expected', () => { - cy.enterAsGuest(); - cy.visit( - '/search-next?filters%5Bkind%5D=Component&filters%5Blifecycle%5D%5B%5D=experimental', - { - onBeforeLoad(win) { - cy.stub(win, 'fetch') - .withArgs( - `${API_ENDPOINT}?term=&filters%5Bkind%5D=Component&filters%5Blifecycle%5D%5B0%5D=experimental`, - ) - .resolves({ - ok: true, - json: () => ({ results: [] }), - }); - }, - }, - ); - cy.contains('Search'); - - // lifecycle - cy.contains('lifecycle'); - - cy.contains('experimental'); - cy.get( - '[data-testid="search-checkboxfilter-next"] input[value="experimental"]', - ).should('have.attr', 'checked'); - - cy.contains('production'); - cy.get( - '[data-testid="search-checkboxfilter-next"] input[value="production"]', - ).should('not.have.attr', 'checked'); - - // kind - cy.contains('kind'); - cy.get( - '[data-testid="search-selectfilter-next"] [role="button"][aria-haspopup="listbox"]', - ).click(); - - cy.contains('All'); - cy.contains('Template'); - cy.contains('Component'); - - cy.get('[role="option"][data-value="Component"]').should( - 'have.attr', - 'aria-selected', - 'true', - ); - }); - - it('The search bar is rendered as expected', () => { - cy.enterAsGuest(); - cy.visit('/search-next?query=backstage', { - onBeforeLoad(win) { - cy.stub(win, 'fetch') - .withArgs(`${API_ENDPOINT}?term=backstage`) - .resolves({ - ok: true, - json: () => ({ results: [] }), - }); - }, - }); - cy.contains('Search'); - - cy.get('[data-testid="search-bar-next"] input').should( - 'have.attr', - 'value', - 'backstage', - ); - }); - }); -}); diff --git a/packages/app/cypress/support/commands.js b/packages/app/cypress/support/commands.js deleted file mode 100644 index f26d2c999b..0000000000 --- a/packages/app/cypress/support/commands.js +++ /dev/null @@ -1,19 +0,0 @@ -/* - * 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. - */ -Cypress.Commands.add('enterAsGuest', () => { - cy.visit('/'); - cy.get('button').contains('Enter').click(); -}); diff --git a/packages/app/cypress/support/index.js b/packages/app/cypress/support/index.js deleted file mode 100644 index fb62f6359f..0000000000 --- a/packages/app/cypress/support/index.js +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2020 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/cypress/add-commands'; -import './commands'; diff --git a/packages/app/package.json b/packages/app/package.json index 0196acc0a2..d9aa5ee847 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -103,7 +103,6 @@ }, "devDependencies": { "@backstage/test-utils": "workspace:^", - "@testing-library/cypress": "^9.0.0", "@testing-library/dom": "^8.0.0", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", @@ -112,21 +111,14 @@ "@types/react": "*", "@types/react-dom": "*", "@types/zen-observable": "^0.8.0", - "cross-env": "^7.0.0", - "cypress": "^12.0.0", - "eslint-plugin-cypress": "^2.10.3", - "start-server-and-test": "^1.10.11" + "cross-env": "^7.0.0" }, "scripts": { "start": "backstage-cli package start", "build": "backstage-cli package build", "clean": "backstage-cli package clean", "test": "backstage-cli package test", - "lint": "backstage-cli package lint", - "test:e2e": "start-server-and-test start http://localhost:3000 cy:dev", - "test:e2e:ci": "start-server-and-test start http://localhost:3000 cy:run", - "cy:dev": "cypress open", - "cy:run": "cypress run" + "lint": "backstage-cli package lint" }, "browserslist": { "production": [ diff --git a/packages/e2e-test-utils/catalog-info.yaml b/packages/e2e-test-utils/catalog-info.yaml new file mode 100644 index 0000000000..d1dea51dc5 --- /dev/null +++ b/packages/e2e-test-utils/catalog-info.yaml @@ -0,0 +1,10 @@ +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: backstage-e2e-test-utils + title: '@backstage/e2e-test-utils' + description: Shared end-to-end test utilities Backstage +spec: + lifecycle: experimental + type: backstage-node-library + owner: maintainers diff --git a/packages/techdocs-cli-embedded-app/cypress.json b/packages/techdocs-cli-embedded-app/cypress.json deleted file mode 100644 index 5de7ebffea..0000000000 --- a/packages/techdocs-cli-embedded-app/cypress.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "baseUrl": "http://localhost:3001", - "fixturesFolder": false, - "pluginsFile": false -} diff --git a/packages/techdocs-cli-embedded-app/cypress/.eslintrc.json b/packages/techdocs-cli-embedded-app/cypress/.eslintrc.json deleted file mode 100644 index b903ff250a..0000000000 --- a/packages/techdocs-cli-embedded-app/cypress/.eslintrc.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "plugins": ["cypress"], - "extends": ["plugin:cypress/recommended"], - "rules": { - "jest/expect-expect": [ - "error", - { - "assertFunctionNames": ["expect", "cy.contains", "cy.**.should"] - } - ] - } -} diff --git a/packages/techdocs-cli-embedded-app/cypress/integration/app.js b/packages/techdocs-cli-embedded-app/cypress/integration/app.js deleted file mode 100644 index d31f7a7964..0000000000 --- a/packages/techdocs-cli-embedded-app/cypress/integration/app.js +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2020 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. - */ - -describe('App', () => { - it('should render the catalog', () => { - cy.visit('/'); - cy.contains('My Company Service Catalog'); - }); -}); diff --git a/packages/techdocs-cli-embedded-app/package.json b/packages/techdocs-cli-embedded-app/package.json index 4d49be6016..9be2358760 100644 --- a/packages/techdocs-cli-embedded-app/package.json +++ b/packages/techdocs-cli-embedded-app/package.json @@ -42,21 +42,14 @@ "@testing-library/user-event": "^14.0.0", "@types/react": "*", "@types/react-dom": "*", - "cross-env": "^7.0.0", - "cypress": "^10.0.0", - "eslint-plugin-cypress": "^2.10.3", - "start-server-and-test": "^1.10.11" + "cross-env": "^7.0.0" }, "scripts": { "start": "backstage-cli package start --config ./app-config.yaml", "build": "backstage-cli package build --config ./app-config.yaml", "clean": "backstage-cli package clean", "test": "backstage-cli package test", - "lint": "backstage-cli package lint", - "test:e2e": "cross-env PORT=3001 start-server-and-test start http://localhost:3001 cy:dev", - "test:e2e:ci": "cross-env PORT=3001 start-server-and-test start http://localhost:3001 cy:run", - "cy:dev": "cypress open", - "cy:run": "cypress run" + "lint": "backstage-cli package lint" }, "prettier": "@spotify/prettier-config", "browserslist": { diff --git a/packages/techdocs-cli/README.md b/packages/techdocs-cli/README.md index 85c0075946..e7ae51053b 100644 --- a/packages/techdocs-cli/README.md +++ b/packages/techdocs-cli/README.md @@ -75,38 +75,3 @@ pip install mkdocs-techdocs-core ``` Then run `yarn test`. - -#### Cypress (Integration and Visual regression) tests - -Running cypress tests requires you to run the CLI locally against our example docs. - -Run the local version of techdocs-cli against the example docs: - -```sh -# From the root of this repository run -# NOTE: This will build the techdocs-cli-embedded-app and copy the output into the cli dist directory -yarn build --scope @techdocs/cli - -# Navigate to the example project -cd packages/techdocs-cli/src/example-docs - -# Now execute the techdocs-cli serve command -../../bin/techdocs-cli serve -``` - -In another shell, run the cypress tests: - -```sh -# From the root of the project, navigate to the techdocs-cli package -cd packages/techdocs-cli - -# Run tests -yarn test:cypress -``` - -This will launch a cypress app where you can run the two different tests: - -- `backstage_serve` - will run against the backstage server -- `mkdocs_serve` - will run test against the mkdocs server - -> If its the first time you run Cypress, it will run a "Verifying Cypress can run" step. This step can result in a "Cypress verification timed out" error. If that is the case, let the verification step run and then run the command again and it should succeed. diff --git a/packages/techdocs-cli/cypress.config.js b/packages/techdocs-cli/cypress.config.js deleted file mode 100644 index abaa324d76..0000000000 --- a/packages/techdocs-cli/cypress.config.js +++ /dev/null @@ -1,30 +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 { defineConfig } from 'cypress'; -import { initPlugin } from '@frsource/cypress-plugin-visual-regression-diff/plugins'; - -module.exports = defineConfig({ - e2e: { - setupNodeEvents(on, config) { - initPlugin(on, config); - }, - - excludeSpecPattern: ['**/__snapshots__/*', '**/__image_snapshots__/*'], - }, - viewportWidth: 1920, - viewportHeight: 1080, - includeShadowDom: true, -}); diff --git a/packages/techdocs-cli/cypress/.eslintrc.json b/packages/techdocs-cli/cypress/.eslintrc.json deleted file mode 100644 index 06965a82da..0000000000 --- a/packages/techdocs-cli/cypress/.eslintrc.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "plugins": ["cypress"], - "extends": ["plugin:cypress/recommended"], - "rules": { - "jest/expect-expect": [ - "error", - { - "assertFunctionNames": ["expect", "cy.contains", "cy.document"] - } - ] - } -} diff --git a/packages/techdocs-cli/cypress/e2e/__image_snapshots__/TechDocs Live Preview - Backstage Serve toMatchImageSnapshot - Backstage TechDocs Page #0.png b/packages/techdocs-cli/cypress/e2e/__image_snapshots__/TechDocs Live Preview - Backstage Serve toMatchImageSnapshot - Backstage TechDocs Page #0.png deleted file mode 100644 index 99fc1ea483829fa3236b8dc3bd5873d841d53ef9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67783 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 O5*$5t-f=j3{(k@|cq(N8 diff --git a/packages/techdocs-cli/cypress/e2e/__image_snapshots__/TechDocs Live Preview - MkDocs Serve toMatchImageSnapshot - MkDocs Page #0.png b/packages/techdocs-cli/cypress/e2e/__image_snapshots__/TechDocs Live Preview - MkDocs Serve toMatchImageSnapshot - MkDocs Page #0.png deleted file mode 100644 index e6c63d5d579491378c3f5f73f1500ddb482d5db2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 170963 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 z%0A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

a^U5l0f~ll@pf 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 -describe('TechDocs Live Preview - Backstage Serve', () => { - it('successfully serves documentation', () => { - cy.visit(`${Cypress.env('backstageBaseUrl')}/docs/default/component/local`); - cy.contains('hello mock docs'); - }); - - it('successfully navigates to sub page of documentation', () => { - cy.contains('SubDocs').click(); - cy.contains('Home 2').click(); - cy.contains( - 'This is an md file in another docs folder using the MkDocs Monorepo Plugin', - ); - }); - - it('successfully renders all Backstage main elements', () => { - cy.contains('header', 'Live preview environment'); - cy.get('[data-testid="sidebar-root"]') - .children() - .should('have.length.gt', 0); - }); - - it('successfully renders all extracted MkDocs main elements', () => { - // as it gets replaced by Backstage header - cy.get('.md-header').should('have.length', 0); - cy.get('.md-main').should('have.length', 1); - cy.contains( - '.md-main', - 'This is an md file in another docs folder using the MkDocs Monorepo Plugin', - ); - cy.get('.md-sidebar.md-sidebar--primary').should('have.length', 1); - cy.get('.md-sidebar.md-sidebar--primary').should('have.length', 1); - cy.get('.md-footer').should('have.length', 1); - }); - - it('matchImage - Backstage TechDocs Page', () => { - cy.visit( - `${Cypress.env('backstageBaseUrl')}/docs/default/component/local`, - ).then(() => { - cy.document().matchImage(); - }); - }); -}); diff --git a/packages/techdocs-cli/cypress/e2e/mkdocs_serve.cy.js b/packages/techdocs-cli/cypress/e2e/mkdocs_serve.cy.js deleted file mode 100644 index d5417e615f..0000000000 --- a/packages/techdocs-cli/cypress/e2e/mkdocs_serve.cy.js +++ /dev/null @@ -1,48 +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. - */ -/// -describe('TechDocs Live Preview - MkDocs Serve', () => { - it('successfully serves documentation', () => { - cy.visit(Cypress.env('mkdocsBaseUrl')); - cy.contains('hello mock docs'); - }); - - it('successfully navigates to sub page of documentation', () => { - cy.contains('SubDocs').click(); - cy.contains('Home 2').click(); - cy.contains( - 'This is an md file in another docs folder using the MkDocs Monorepo Plugin', - ); - }); - - it('successfully renders all main elements', () => { - cy.get('.md-header').should('have.length', 1); - cy.get('.md-main').should('have.length', 1); - cy.contains( - '.md-main', - 'This is an md file in another docs folder using the MkDocs Monorepo Plugin', - ); - cy.get('.md-sidebar.md-sidebar--primary').should('have.length', 1); - cy.get('.md-sidebar.md-sidebar--primary').should('have.length', 1); - cy.get('.md-footer').should('have.length', 1); - }); - - it('matchImage - MkDocs Page', () => { - cy.visit(Cypress.env('mkdocsBaseUrl')).then(() => { - cy.document().matchImage(); - }); - }); -}); diff --git a/packages/techdocs-cli/cypress/fixtures/example.json b/packages/techdocs-cli/cypress/fixtures/example.json deleted file mode 100644 index 02e4254378..0000000000 --- a/packages/techdocs-cli/cypress/fixtures/example.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "Using fixtures to represent data", - "email": "hello@cypress.io", - "body": "Fixtures are a great way to mock data for responses to routes" -} diff --git a/packages/techdocs-cli/cypress/screenshots/backstage_serve.js/TechDocs Live Preview - Backstage Serve toMatchImageSnapshot - Backstage Header #0.png b/packages/techdocs-cli/cypress/screenshots/backstage_serve.js/TechDocs Live Preview - Backstage Serve toMatchImageSnapshot - Backstage Header #0.png deleted file mode 100644 index 867e8ddd8131f19a8db30f7fdf12a74dcead1947..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 401484 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�V7*p%`TfRlvg z($$Tq0+8Vzk##U}=WdGuo9|yeXC=gw_Pm}*^-RuFhh07+e1Z5Bd_pC|Jk$OY^ABKR z<+%Hul`%^yK88a=iYSUlX+9O81e-aTy%|%3$P^0GFfjDP24jgS6}TZB#@_aw8;7ag z2KjWedVGheAZj52g-*M$`Ikx`BAe#r9qXwT)LO+XrDyE3Sy6V!I-TvI%svsRe%@0M z^~!X&@Laf@C3g6d^O#m4&@CO1g6 zdzCcsj1^CR;CAfe_dk<|C55tdHV-aGnk}!?T+D+*{3klYy5 zp=y+{e+oqn%xRC$QAqf3lt|YWh-V1MJOKvJm|5jZXmHt}k}!=p0SIn~O<#SPJn+ab z1<#j>Y&dbAj456H_r7$$R{d(*(cVY7`%L;(rUIGDHnpupb%0}el6BM>U^~XQ^k_uD zsfc6J3(Uf?gzVaARzRE?AOgIIaeNV=z6`Tnu=Ge+g)LP`0l+r%6^s;w=y$verQIbI zBxh1HI*fXDyt8{|Qa*R1+cp_B)1|Y$qZ8WHJ$O8n@+p8D00|};8ukP)7&rN-wAgblLBu+r-}K0!!jhqb0nLJT6E1e;+8IcdG2 zaAwvJU_co;LH6q)PGNFwxu&hP#TT*V#muv;V}cN3!yr8KUZ(0mh+KPK)Ap6|@PO&Z z&n=GzOkeuguU8M6zT73(Cd{TMv>Fc=k*kW%zm=i|W)1#n(;h&Lm~6!EEIvyt=+2a? zT?|U#a>o1*#Gt|T4BMnKS7{kodh&FWMLO&E0`!uCKny9s48q$08${%`=pH7^V6j?= z>Dp6bQMoASM&v}HypS?U@c}JzFXj+XnuydW?Pr?l(+UIA>bW+R?diImPFW*dD$cqA zR@F}VmNLz{R^!P*Q^Rvh%xt>Ig5sHrq2^fcUK@-A!b6$usm|f59#3@SciV?`Q#S#by)bOc|lpf*9xHRZH zgeKVM1;D^wY7j{rJceQxNNuo~pe~zs@E=BCZ0xeOzTy3?`IJPZCy1t;>EHOMQ&7(h1d$E1_ivy(#D%1lRU80wo8_JTy*XPk)aSfe1{e zhZTrLN4o)F#S!otN$&!`EkTGlv|&^Bd)btcrXc+nDDiKft;K1yVIGQKTXbSqLs?9O zXiz`0_1f8eJH6gmclzW-p0=uNj;ktbtIR%QA7eCELY6^W3>m3`|D{EG81k}|8uK=L zcKFft9y1>c&eK$5bWKvCxw39^EvfoB+9sLW>RZb&uJWOj?WP{d7)Pf zntw*4yiNBtgY0CuWdC@%=!L#C)SqEJcShho4~jKK@f;LLEaOzYhN3^38)fesOE}F) z&LXh4$f_iU)OkFZy+C4@JVok{!;Q0RiiFqZ0s6(>(6ymogJj@E&O+iFQ64rw;p8?2 z>>B9i^GY>sDmVM}sUGO?Wjo|r`}W!N5k2^ZIC&<`!&CDt_}Gm@0=L+|i(g@=2i})) zjJHe6w?!vhRhvxR_5g-{s4G^BFeY2U9Z=}>4RPFZc4Lxwgw4+`tD-An2}_C>zuSHJ zBOt=aXC^hOczG@^C`x1oo2`U7zhJk?*Gaj;K4EdvoRNIIL}e07gVJ8#ZNH(OfgH;m z(`pk^WGq}mY!8ggH$4~KIr=ru}9V_wT(x0S+iW~+AH ze{`TS1dD2)kvb6Ja-lz}Z@7iiPh2KUZ_;TrLk&V|60bRHmE_G{3SmkPe+FcY$;gX6 z4|wyFlnJBTNp9c7=B2R%68(qhjKkcjtn#xTx1BlM{^OuaJ?FX~J^b5u*EYZQ>+GfP zeWiJ{Mj3z7yyq`H>rDQ=C0qVsA_9>Ix+7%@{Fiq>gdC{TCz%XimiC0)bd2?%AkymHRRv3M= zy+YT)VB9x2k&<2;i2glqL??rhe^_z3A;NUg@^$(U9ZSi8j}B5g1}Y!Kl{SYKuY`ROBI&~gr#MVx^!)=jZM)HQ=M62F(8H`svBG&;%VEdsEKz}jbc_H`{KbF?ZiXt5Y97w z2dEh7D}ZEid01b&e1E1_NWuB$JveWeo}MC}{mMyt$ocv)$E?=Yr?Y0M1dY8TxHSw5 z0~AHcXkZtsfMU(Sk9u&6(4~HwCk!NJIA)YkFt6)+3pjq*dln-$=y^#|*t*{(r6S_>=ppaav;I5X z%W^+LttGVt8jlouG0wBk*XxItr)K(h((jPsja+@%i*9<#!}>aJcO7MhJ@FUtZyHe{ zIyKV?{vgsy;peT^A#eZem8JCq@MVZJU9yns!rcI`u_#l4rPp`KZy9kDr(kl7?=5pF6)vw+k&l#!knPa3lVf@PyK88tnYr@6+g z+>Zv@$wo4R<11wH!JG6Z79od%W&9;A=R zv7|GMsbCddw0KYjr&?G{{-7WbhOj+NbTo|#Aj9gJVwS~=idJbcsOAPt=Bs(CTw~2l zHZF7cK8X%a0&9vv`+2n@6=b1+q1(YI+hJiy1L%L!=y+o67QQFVVzi`D^vQQSOM9q3 zIK>=7H)jO-1uk*E`SjU)6r|}odZf6RU`DP%vb(YdhF+8_M&c7-FKgp{U8F=#Y`?_V zKWo)WnOpGojQ3~$fD6Ns!0&CH=D_uy`ixkd5!O}PI0?m?_X}3_yb>jsI=zmh`-m%I zB`y7xDEae*yqd}Bp&^B|4+)QlC(6#%>*ruKWZmzLl+&Q;SXwo@M z!YPgH|KEUqt}9VBT_CsGqlCsW$3&!RZdg8Rn~Gj)8T$(oa{(zxG7L>DfYBle@B%k2 z2I)m8Cd5IpA6nk=_qUVW%>z2x2Dm+G!sGl zroidsk~u%4{anJR$$L6kF=}dmY^=DZiA|R4`&GHS)`dpzb6I!ylO*_>Kf@jlzHJgn zUly=4?d+&`S2}|ISgC3My5gcms%{|IK2JHqK$_#@VMALnRUg*6Hk6%2dGXy3(B2nA z(&xz~DnlzmqDUoT@E5~-C;@_DsnP*(-WR_L!}jRE`2@{BKV7Z~wD%5rgvmR~VDHX= zN2q-3?57XHvQ;tgPhQUe-q*V7<~j+!&j@y`u>KD88~nPIQMD$7!v~NVs5)K|46z|L z0h1SLH6tkzRS|^0ktz~j8sOU1F<=Ny%N$*fwUzh_%P}~`Huz?u%iz3slG?2vtlU+Q zfX>)Qx2dgK!60*hE8&TBuL(RAt&eOKZ z9jw&_1ZHw2&_hSd2dv<955f0&j<`sLg-S-20NNo*6~mIIJxtGO{)#EAw5b8ccUEOE zYEM0T?CrD8mhxoxe*gPUwQ=OEn*_EK0{mTf*EGc$qsH-vRqDBT9rU7|@nYYAQOrf* zwBPo>e0X%L(Na4)E!Y3%hj0GoN58)E-6F)!DxHcOi5 zbPwwUy>7}Vm~<1(I@|Z;!c;+tDSG>I(=Ttr1k4xLJ+;00*H5)Mx^&j7%Pbm>3$Pvp zIKt}jclV|)R0Rzw0Nw+(|9^G&2NF~zq4;yVEHk53X*S4(4tXoZL=r?r0GqkcOIg-j zGFS;(%)DJOY!G0rK;z@S^nNd6p8lg^lfLJs!P1iyWwMUfXf3u69=D~d0!N1fx`^;@e}yJ=iS~SEHF_^e}`zwK*WzXmIf#{bOFKLPy+fuU~Lr;@j)y}Anyur-3>X#<|uv9P!_C~6nKjEDP5E{@L|4pg4=$vctfX|a#UGVEFMfjspc)}t({$l|Q_%N~js(Sneg-K8z?#dle(H{0Zk#eu#v zdI)*j61jb~Tr~-O^Uylg>_g4$V5II3x1Ne=Jnz{nnb6l;Mlu4r4ftz09^b);2Zs-= z0~sm7{vt7kkrae==@0)s32czQsR!n#uJlyX!{W%a1F(Y-tb1udC^lD1&YOA)H4byZ zDKd6hf0IZ@G5WRtfKyV`wu@GLP!6trFL_=6&6UYfS=Y4nkJ~!>ZyJ1|PmYJq*$9U| z)2WKlVejeGvvdCUKXT_+a@H)d{i7)W0O)YzvwC(o?0$ zx=Gg8W6-F?95_90#qsyW#IZ*C^O<4BBmkOl2yM68>QVV&3Gy1~G-YCw>Ga zJdtFr$=Da{CBs_48Z@tgHAYY+B1xKGhD5oGu7#O9^2>s}lR4k(A#*^b-p4xftX8AC zFH)FDQ(1Jj{3ypm&D`KN-CtK<1pI^Wo6Q3~AF2ro6nR-9EdXhZSWuK)6QD7U@*^oD z8o(KD2BbYm8VVxeU}_SBZJwc$3z6=`CIPVOL|8lU0~8AdDOhOsM=BTZnjn#Cdf0~( zY4akCmda{=-o%ffEW0Oof3aECum`Al%SAc7*{9omv+tL|B>%J+$QR*s=TUI^&H?M+ zPywm9$hh@ec~eo)*(%2_xv1CY=(OeJ_6 z4N2NOL(?6-@p56dK;>uwxU-5d?8$h$cb>8#>VSI*{C*vSWCZbfKL!#&v>-mUfrxp3 zf`e=(!rNF|Kzai!e$nF3I*ZQ}q1!~CzX_gd4O2NrwDxCP)Fz0hDctCW@ExVy4z2L} zM8`wjHz$QrqwV>nsG03_SO734jup-72L#R+N()?eOj`@P07+7`$&!)uiro!QF}RgRjQ**i&qGMIrsC0XZs74+Tw zegHcMC-j14+VKq_cbPCd?Ws-_Yxu>Gom$u_5z3Lwe`B3nN?11N3@w~&i8-99L;MFU zC*eSkAk{^t8mIt~3UEU1Vo`xEdy(Y@h^7QYlZT3$gRsU4w=Y}d$+VWCLGU7kc_1o0 zamEz!9SN4F$}%mUJyeUt^~$k0@W%cKWEX?!(y+U2=~Fd^Dt&56&}EA`3Bh;8X_6tP z<)b6~B58rEoIa$Dz{||`6litUkLT*UW9BtK))&pG|LezXYlf;D0`n#fiBX0Q(;JPa z-v8%K>sBBCkJith*WY-5$K&^Ueq8dw{ZDRvclE(jo~%f1!r$>*W>c-psk|j<{l&ZU zrpsteIBN~Y9#glDI2>qw;BK6@HHkyi8ux4`Wmy#Ea~iP&@>B7Ua-&0KBI z@C^F;`01~g0?ec|lGn16}-@PJAyDvt$6Gb(G5PSFveiXR?@~X*#hxj~c|oqNskv<=WKEgz z)^oqJ!An|~wJu8z?&v?KNZwuTr-?1H_|dPk7C-W#$CoWMUJP@Q{eXDWo^ER#rU5*B zirZ6S&>dNVKsIln507;r-4P?247m)om*pl5)er~UxbR6$u5TI?O9LV zGTDx=f&SyVVcb(Y;VJwM+#*rfjcMgkZcwxvUt=P~ZWBkR9z#{C6N}a4> zszMCALC;~KSs)9n#=z1^+PZ0;S1`x4`I4|k5aNi(JJJXzteP^>FUjnU8jvV*f8n7mQGdxl6^Crvg!^oZ1uh(6fo7Wv&`&)e5|Ys*z*{ovY?PZNZ$Ry8yV*+vniC8;_`+8w@{Nei3kKCjU-`? zL}<_Vke@YfM6spG=0Xxdhy)eFKHcc%G1yfZoT$@TTqy9k4r=}M0ZEN4c+)50Ji;M9 z1(A-|tWHF8|oi{r=#ub}vcxSM1Je8NA}>?pt2ppVFQJ zac{5$WUs!v47*<(Lq6j;?3JJSDGHKfi0*OoH2@D8$GJL|bbEV8nB4ZfQ>$`VWI=M_ z7-$K&8-Fq4KTG;B62%62o-+ylx5uia(REI-CI$u06e$-TbPVdjaT*04N5Kdo0;|q( zSZz@YuIkxt;g$@<+Wx$t+cwkZVe0kwX!GNN$BvP4fsYb1sOD$K#~jvfhf??v_lsp9 z{(c(^o5TDCQLF|U=30S5w$ZQ-G|JliLl)4DeYf!#+AQEbd1NvQ%|cTIk3SKCL&V_o z_UC#Cm1Av05qUa%aLh%CJL0z;pD>;O03zm)FgkPN@8{Y-*fcl32ZffoSHg|P2%z2b z?M=@Ngy605o<^U1Q=tgjAXW_tkp5dOcrU_xkWi8koJe=#>r>30r)%D?~p+N%Rlo zmWhJ&oDS+aD2LFN*{AI;9&=lFPsN@y>$i90L6Aa8P|9;3;7}>X>m}iV3||4-*5<^6 zi^@7Vl(u!1@OcdK%Vdb~EQ=Dqu0xFc$jzwYO~iPHi|(Olea@-)|ZA&^*r#H8y`4r|6qHE&u&R9AzT`= zo`Xhu9z~%c@gHfZ&(I3uM8H>HP+v`ekmg_(u%@Z3opS4VU6dl(QLldPDYf6yD2gz# z1Ctssp%Dmv;FR4_`9DJ%4^&9{b`lnpL;=Oo3vv7u=G%FKg#kSV;UtSe zDXug%#fe1TpeW=G4P->38ijy!=QWy8pi|Otp^kB=(QDEW zIS{E53Dk-T2ngy*_BQrM{n~Mwgn>N1!n)4&HggQsIR)g`>2YXC7U|{Db>!R2av#oL z;94~_qiExH^ZKlyo-6TgQ}n(c}I9evC-SOu>xce!JNd#@GYTPzaWh&5ke-unD0X)*`;%>jR z2jtN)eQ-cl6qFSbbhO~2PLjk?J^GJF#q?f%h7AAr)BZ8T9Z14aVPT$P#-kzN85q_mqvkxKJXzeAKE)TK|(eE9MP zq&FSM5qw0*4KQ{4)^jeqmm_EfktG?-!y_m7Kk^|CcK(Pma*4rNf z?O_!0(aNG={X52u(QF@s1QJ9BPE1lr=wci*-!@BUCgFT zmP=Y7B$p_J5lzb=;F}3nP?0;nl-n)xnGv<)mneFKIsN*HoaFZHS$snxNwM&*@Cai3 zCQ`EV6BP9o)Df<4M5mBYrJ%19Wzh-Fv+$}oPN^a#m+A2khE*&r5w1JMfy$KX{GlG9 zQeBih1O@TLv17p?K-xXlzwu0*sQosne}i;1?d?rOJr?qDkQf$Me=`f?$)ipQKPM^* z;_i^%0|jD29e{$yL;|ITYSh`g19^nlBl)BVAj}om3ZWAKNxI&|t3VR6(*yKDI`vXb z9E>xYK3ndW>4q9wq%=8|CLAnF_CMQt>)c9bO$DDS!iqhzgTRicsz9GY)N>r*iU;%r zRaP33cUccoSHQEuQlHl?JcHQ34=ffM8S|nyV(Km0ZxQW;2Hk`>P9)R&(7Y4#zTj-M zKh1e~K`_wEqVq7WmSO!WKuoJt({dZI>be~dqJX!0H_EONPRngu)MITrp~`eM%Ebx; zz%cF!vA)s)5wBT5F#HYLZ6C31A>oh-qZ(mEhp7@I&?UmK5cyKrvt)^1+pm{=_&04; zf^y`@HSI?707HxytN=0OLj1fvlu2Co!xwu!|FAfcfoTS-i*JrLU&;;?n5 zfa2IRfBk4mZr9+!H2;p`-ABto2(Toe&1|aqKymE!kXv1(sr?3A_|WgD z)({N=t^Fa41nwqe#V$D2w0;^;T+^zB&rG4J!ClAt+sxHivz69)BPwQa@tK0rYo0{Ya&hWmnYY>`aOoRr{Mx+z~UgtxTirqJWQYmLfmgE1zm$~b*+AqUWi)? zbD*y!f$7AniOkT&KzuzzJ-lemyA)@f!6v?R&(5#GxJJNF_23;eQ_904!w!vT;2;ww z;5-#i7xZJ14y3d=;m<{%uQR}b07+a{ueC5lbSLur`G`0;qeSMBdl#54K-!t=L~4Ten+( zv^aOf-`$7y{~#a5yC3rn7O55T2h8FeIZ5ej~Eb3T&|)qxbxGOn$R9V8r|qUaMy)T83x56S%w6 z>hV>M=UT@nI$_KK!OUCa)*hYhq}(O^UjhVP#l<_hufLa zpDfBq*g2yakF7P9q#ZS{K7M6%Y1*-X+i>1E8dzsB8>#}3&B?fUIvUhDsc5U(Z~UV> zb&>5i__7sJqt^@f9|ttth*)HkymH#$_c*|K!-6(FZaQeW3&Iv%oBsav0ppFft3+v8cb1Qoj>4?d!^>2+4RG?Yxh)Maq@yn%{v{&->By2qsHTNKF=Iz_o%6( znEuWMQ8I2)_4mXFiyOGE4IIfqnoK|n12GCS&D6{74Kl~9NAUs~lfjKQL1IfJ zI>qN=ap0W47m+m_mP@jhow%yqqI*cDxo{gtH|gwsVGdij(2^)T8%wQJuC0r#PzIsO z2_i*{%MzWC{7lu~VGNurjF(%?@g-0e?iB&JSh~V-MW>Z?rNa*7tN${H{wemQD@$i3pQX_Ill%)^1hL z6v=`8V$g;pZE3i%X8IS8Pqx3Dc5n2vu8nmeM|X(AzP#hcz0sc@-GapI9X+c1nCb7= z6|~;~lQwiMTB{GML@&oF_0_RZ7;qO5S<1s`wc}T z2;~0gy4#~v?x(|u1dUS`h*ymLum&8C6fsGi{nCKPdk=6h$fGkdmmXT%FSvvQe zA-%UmTzD`ya!)Yvb-f}fTKE;a*b3`vLMf11!#l6wcg`ghD>=_%(&2AZ*SHKwk%;#E z4sPt-*?!qO^6cjOYx{rR|5EZNBQK#IQ?mFXF-y{B&LgmS9Z7qbl=gYu$;bP9M}L?G zeV2JPpSIl>v7$Yt|)gd3NB=jpNF}D<|83YX0HTSL&96IE}uX zb{x921~G+pcvbE{Sa&IzLDFvIZg_F>gR2OwR_g0vv09K z)i|Eno~8*8GNlU+x9KnAfQz_Z%iD`%K+N9+tc_r|q)M&rwsIS2Y+b^vZZ52mP7z8% zw?de<2}le8f{jBAhJlxh^H&UAxmaJevgnWPl;8zksBuOTj*Uj}5}`1|h8*>wi?J0C zG^Wu$u2g|Pq~>|&7O4R_IXA)Jchqz)HckA}Cg*kypNpOLH(l{FUAahCxD#`L@GV_z z8~F>N51tbSJsiU%agCgbaEE3Ss2--sqb6I^jbv5d6F=P%b-%62UTE1o9S`c0#!puX zDwMNALsT22{794cfJ5 z72~q>4)^x-(iMfsjQV^D5sMoO%!ys@zNzhBM@M9_9esqJ2_6bM#LGOyzsQBqh-)QK>Q?VNhF$iiq{ZPXp{H-T{jhNnXV@DbIfY={ulP)U-CD zn305&%@hL~0*%Q5HXk6G7b2B{lQ}||n7q{|M-bQ`7Il4pn@l}DY*c@frL#9As;vR0 zwk>n3+K@8|;O!Ggw?jmfPj^9(IdE!&k0Ck|sZ;F_{mesdM^jf8G3yFlOa`wiGePI| zFM^+{sPVYLYAn?5;NS7P)BDLXQ#nl_DR_03B8cf7OE!iI7IEV|x(;9byVV7|83VYa z$u||^gwstRark=^6e_ZirS%@E7i=pB*33QmJCyTA*h-&4m;q4T2=w;NSO11`rhcLtkQaxE~ z*`wc?Tj+*0s@}721Njz((qP4jv?@@Z!RRvB-hVE(2s#X|O)Wd^y$soIS?wUp!lyXW zU&TdGBB=g_NWcx;y-4MdflBS*mt`0cEI!4oqZQc2KEZ}(d?SYwr8A?LNgg7K+*mi?hOVl(3J;a+B zbC8&iIP~LBYnHBi`on$4PQL#UiX%+N9p`aQdUQFyj^M8s?EIqoosP@#4E3*_Qcrw0 z&F_Ex=+NID&<9LglRCVL{^@_8UvvJozxwn@$UDFOuKW3}SLT%ebnRbv?fJ_$kDb|y zU6iXH5bp%;x$IjjIrSos_bL<`{&8H7mup%_P4lpqw(fd~+;KN=2jTD&GJaQaTUR>Y zM31gaPOH8apslmiI&XmE&87;dmpXD-Cw}XQ;dqxM?8d&%b)9QLUbEQydCK-5nD)`m z6}H*$533IKu#fSv5uD-S<2~(j-@ZIqUXORdx1M^sN7q`043`45$Tg!BzOJ)l6z+=i z&X+HoLV?bNI&CmEKlSc~cuwF~UI4LVnXd=)Xh^87+Qs&%KLmGoVNMlZGRT*nICr>s zWqRYd1)1y&xNT4y4C$A#_lMCoTL23v$OMJ4o&+me9(}Kk`-hM|T;d_isrlGncD^S| z#l_eNom7acirg|ZL6bCE z19lQZUJ@v=>ZolVR`sXKEw!5TF5~st^>i8Q^+hVYqO}QviAB$*pH*!r(?G1N^hwM0 z+4KX%O#~aTP<3Cgt!KXR*%LkB1aC*SNC8OD8b?<*geld1sIq@ToMTATH1MkDe(n%V ziOWwc55Sb|r4`dC_s#$>4H^Xie1GDcL&D*bh@(D1;1cgkUE{$=i1>=5=wLz2TYO!J z=%ofeXUr{YGj%)R!!@#pQV)!?;I#t|*O89zVcf7b6B&CDNFhNSpjf$cNxtw`c=-8b zBY_*?JPKZe4|hO0P>hQZwY+?%3Ph3WSR^X!wZ_GaOdlc7ciM`?Mes~ESi!XK`x?OSZtZu@DSV@_z%%}fhmKi8@)0ID8Z z(sUiT#}dLs?rN7F+sbHRuv6G}|8W10Ex%1~xqj$?k9e4{3N5XLmi?71fi@NBi77l@ z$_@L$SptYX;Fb;Cp2e;a7t@-z7o%L$DP7;U|I3!cMWDIbVF}>RgH~0VegYJvsSgtJ z+I+RJuJ85g^aRVJ{x1>LNgB-vv?cNnwjLLJQ-(WVORi*N35POkuyK$QT{!P61K4S- zcmUMmHS(CVJy~-ZsB*BX0dtIrLa)MEEx>Itg`3kiDK|*@d=dv?C-?mMuYb{8*i^zc zWMMw=p=F_~!2AaJo;OJYPgmdTM>*t@?^rxx{9}7ce6TY;j@j#TVyaBzAdi3f z*r-8X)5l<8GRB`2{+#Wx*!YaIW+B3XXh{df<&N>fYfg(oqZN?%{s|ijKcdf5*tk!_J zk#%;HrgjryQo;f%z?#c4Onud{!M`&kUO525!In15ft8e}cIrz8+kM=XWwAz{m;Ntv zSX+Yv?)foa#0;&~7;8*17v=`F!upLsm!sDAGO{QkU9rx4H87?Kb&jv{m||WZ{i@9xWas zIx<%;<=r@Ajd^`RP)}w2J~BapR$;(vXn>L4vNeh|I=ucO4{PxXh(EUbXr)Ulqq~Q; zFYSDdCI|)1Ea=rcDuYgqe6GklsC=#SRc2YofrrEkbL zrSB~&Sd7f+HC3jkhLS9ZK;d7Km209)&ciyFtWm|2 zeq}{Pcr`=^43AfS-LWAR?XoC=I5bzbsV&MrGqP@Kz@)Awq|Jp3v;dX&U=i)~Bz-Y- zIM6|o^Z(u@r^U{mcAn_YdEKhXVOXPY8ls)6r^5vBVjIy-bn0edLUq=|I0l$1kZ@m5 zqXJXkf#r?NKar&K?c8_FimGqw{$WHg#?7ZsueQm7b2<@q8qaExDPA74p?;v9BxeV} zKXwG-aB3ssdQd-GG*0u`XJ?a}BpA&Ld*Z2{aaf@6f1^16ihWLgiyN1dAO$Gq2?;`> z9DpY0JVE}J#faHI=$FnxP`FD54z$APmTZig*Ao>&0An06Y$|XzUHq%93X*&zf#Q(C zymY~UqL>$=8(k%N4HyeW8{>ikiIE0(2LDSZuXc!4OnxA2A&3+j01EUXaRbevTuR|2 z4Cc0(`oy0JZDC?XGaU!D=08@w=znmhg=8K{&=)Zm60?a@Y3PJ{4N?bY`|@;yVqih) zF$iA}7(_kqHAn=TS~JZS3TnfexirG({sRc8X)``~DlLGDB$}X*`69N|wi40$O2ZT+ zoGPR-C?yhFC~+0&>hN*89yMtkoluG~2-t>o2Oy3w=qkRc)fcOFE#fF`>E6rR3U$4B zN{wWWI_e%kop`Ae<96h{4JgGr7D0Xq$j3_*PJJj%8&1&4Am*Qm+MA3RXnEelX~|~t zu$#<5RSLe?5_r*KMQ;?AmpVD34$}GgOo%7OqmWbY8)*1E$_nhTrb|&K^IR>3SdI4z zcNhYX^nVV4q-ZI)h!utNW3G_p$#g>hL*t9dHd0|0<06V7V-_@7@x*K5RbsID#ZR)L zgBP8ef#xwcDRVrLIi@1jwyVM;aK(|?rdFw^nt`fdwXe&Dx4$Q}tat1C>L1*HoxZ>O z=DTrq*-{uTT=O7qMfq{a%mO*g5t^$ z7vOMQc_(YXzxnrw*0H9Jw#hR>q}*YF!9qAGFb>hp+wXh3?W1Wqask8~LuQ4QvSS#{ z0*9_(^A6Z(7$FW6lF>mtDMmH$KSaDEv5Vxq&6SI#GvJzN9=tQ4k8aJYFOw1Ov2SsG z8Ck3ocwNZVu4d>DUwnLNW!=yfyn)%I+yqab{KBT4anO=ccw*s9Mjzr0J26;*!$rNm zQ0_vY9gn`(V7SIG5QMSWKa8z*(4{<8G1=FQv@_EWO^=V z_E)Us!s;_@>I0f4wMFmYEgN04r|{zay@xz~itjtuYJ#WhS_wZ1D365yCZWO+yZ6Pw zeBm-uR`uZ5h|J7V`r^~xSBcp|2qQBkmonCr%Jg}1+mK$PN*0FYv84W&FR8x;!mxY^ z>1`Gh0YvTt`v&LpNGUyixDdW&+(_lzE{h&kzXNuT9<+Dcc9;ZPj3WurpYXdQ1E^#w z1g!30Zh!D;5@#|Y#w@jB+?EvL?rc;lks#z!PABDUfhQoZ2I9+foHZH7gu3$1l1RB~ zya!ZgXt3j*a@(lwY2=)>Rh7HHxc)NC#JC@Qc#DuP_nw6b2s{e`o1^8c>9WM>o=)=1 zV|6Q1D)H`Fw2{0!kpBn~jJ^hN>rDkkobV7pKA zhX8`8S7_Q1P1f378Or8*Qt6VwgvXePDDChelL$cgW9ovh>S`up?piBa{*kp+5GWeF>&#U~;U^KTDaq66R8Y8T$AV znwCZ{&s2*X5`ZN8_Sah@-IE{UO~w9HHo#DGJ6nM1xTSduTK%h7Hf5CKiLC|1H$wXR z|70a5`$T=BdOBVQPH!-g59^Q#)51WWFcYbBOs45<4p-AA8F^ut0op}+Lfox1p0=&R zGxd3hM2;DLe00cVMoZzJD8WM{?#L`ZhN+lWyl(%rW+|-8RWTfkNCNv`%zu*3%^*I4 z6aNDp9rfT$7+`?_y@2x!C_e^sLslR4P+$ceuS$6o@j%vAZ$`YCn7R`qp4FEKfu>|+ zcDz6iBnaS&Y3XPB!=u`GvcbF^Ocaw)dX5gZd&SkA8Tm!^NyR$C@i;Z|b71f|%^(50 zte=z2-r*#mbBGT{*+C}}4QUhty%R#*3PLy`lp@SF;k1*3Y4=nI4$8MwYSwiafis71 z@a|D<6K9o4NM^p2u7^2$Y}0@!d{3V&o8DcMcKgQa(c<^V@G`7vw^?x!s?nM{4EuZ= z@G7RrTEPku8#N9V9W1)SNIc}*+U`u`NeAlD?l=jjYA!tpK0xQv@DFhP#LsE_^*gEq z#(5u1Y{RQ+;x*mC>{XNpW)k}mB6mhxLQ+qbmNxsW8Dlee9DoP^PrJQg^e zdt_|;wX{1oULAE$8auAsaV_oMjgV1yL>fD3K5%gQhjr_?^dN4S{W>Mkppb9J0#5LR zm`JaH%@j!zHl41h*a(!QGz~ zZJz`w6Z6*b$rOSlA^H}+* za!b!UaB+$gAljtVhdIls!4(8>-0?TkrMK`z?EJp^p9$qaknhBF6m?}J`%tt&*m z*=4uRpR#TZtY@t4fU7P#@CKP$SAlyycl%U57*?w+Sy4$Zaz3RbW^pND31<|U`^YM} zYseDHR3@lX>9_ixqQ(nt7?{|W;cmw>qu|ikCgpam!y(M9a@b^!Mw!sk?WdmQ)laB} z$V*vVvpTTzHRr`@flYviC(?e_RbT}ORX7tZFo>#q^lC>QtUpUS3j)|mc9#H~X)SYS zzlmpk0On#VOg=NIA?!@XbwsoPIKwj)FK#YMok3x@M2~aT7*b(yv zeE{F`s=>}+^K~Pc-q*gJ18L$-#29Y&?MJmLx4Cps=Zu$R`qAe-?ZqnKg5|}gfp)iB zzOt0~1bL&_7!W#%%?;aU>$j+9Urhp~X*HfO1{rZ=0SQc;Sft7YIFBF-jI)}I2|5@e z0<%qOMv<5uCFZ2HeGr5^(lHaJp6t0A#o#jor>L4h1)v;7M1u&PhvhnSWhAV8Yqp3eFgL*pbnKX9w_)Fnc9mb z{Jryh0-1B3qHwWioGE`RLch};x%Q@oB zz8?75hoArEpSut4U!wZgUrzksKRx@8$%l%JzM6#K&WuCBKAJ+~{rG+#OGkfIOFTXQ z@13!MJ1QMBdYyGxJsYo{liNJhf?R;TZefSo4zXtSa@)hXX4#!5$8Wr%e03_+oYU^A zM+X?RwImjG`|1)@o&8n2B!VBSes~n9iQ!gu1%nvGdNRl-^L7TDpcFj+@F>PQ6dC;@zKqL~i z_!4V~%k?BmP^do)?y{zsT8qQdVCQR`_+g3(aUo&xLrxu{0d+Zbgsy+l9-%MsXTf&y z#rTIP9B_0kaKNeu4dnqESW!{3ItTh!{o(a#8MPL6jCLk2 zW{gf;Yc_dl>XxUiAARd_TurlYn)PvCa)EJw@bqTQT)xrXWK#9D_O-@A_OO%i%+yY+vdN196 zRh{jqb!4Km@9M-at^Z>C8zd}{3o!u$i7?jBbT=jTU2Q^zL0{PVng$erN663RHVWgKL0mZRo!kV5eMEO=KQeGO8c*!AFnh)di(N%6J zS9CcqBVNKDrU;hk8jXnG23>)qAtPxjH_(*3s~GhZdxOCu%vW(SBo=r3>rz$2wr#BP zI>jF2M{=}2Bg_eX13})2{7m!^@lb8{MN-h5SkUdI>(g74RKw`5d1UoRxZ`HsyR^Tl zzKCkAd}0uO$zCp-<=R6|p1VB1kOwYiE7+g_)e5>C6kh37Y(kjuwlBWM@P6@A|N5@= zqXyGx2HE5SrH!mG3+tl}N)lZ^2d|UKDTejpsC9cUvHzkA-pFc{i zyyLEHt=NV)a7t|hXT+Iu-6Q3h8#_A0&4xJTnGxWMbfBFZrmE?TY7$%P48+%BiAUf% zgaSUX(OJL2oea}x2LYYWFk=Ky_bS8U#s&>fT8nR#2PnhRrb^vzs2EF zu`MRif2u6jdDC7LlX&9Bn^R@51L?{xtTC-VbQ^;u8qjL}TOo(;p%e0cz3r^b5{sTz zVND1@cm~~<037tDG=V2&|J9cGF{?Q!{|3yRV*r2SqIp-rjaTMkk7a%H@`l?XA1qy! zl~rH=^yxQetvz7h0~gWS=Q^8M9&|Dn-&9%_85l_s%NGSv1lIw+TU2%c{b3>&X0L&X zSfVOHNvUlkM#rq&c2Z|+mQNg77z3M3O{FJZzP>H;Nzvx9mi+1dCM6WoPIAMrb|o?K z@Ur0rQMp1|h9EGMaTbGDI#)g(-;j1)?>?5KSEgLw;k+TI*%jf}d9sbqq%Qoc=?U_G zQVJVop5aMp)%1Wl$bYV96=ZIe+M1`HE>PR+q&Ol1s}SA!_iw!NvdRFPL1)HJoJ)6!uB{A=k13%PRp)cfYA?e!H|?L_9b3OSO% z2HS2kVI)%Y{s-Fwj{$1NLdw|-{W^MP)zgjqb|5=gLKCI4jzTJtTK;~obY?Jtr{=Cx zz~o?(ls|G&5f-QP?2LdMLd&7y)Oat0Ivx^Q%_sVe>p_uEN;W4N^RJqkl*asNaDu{` z39@6}NHXWdCb}tmP-7xzQ6ulK3W8;?_$CDRMbP`WvPK5qKv%)E3`Lt_f)=ioivlWdEBqGea>#j5#4Rtkjzeb&UK;CZ9iS>X8 z^89w!N*WJiqApqjd?{Oun{5ctdg3q}38J7(UCaXIR7F4p8JU3@hdDg&|GH1lGho_% zfA=u+%rJ-Nx$o<~@9XscU*6kSk1mvmIm($eE~goWHP%9+o_S0CHy+r+SSaGt{!3Z zW6zJSy-0;uO!-dyH|AkC#H;*=WWP-QRwH{x1m!n)^-htkB>V{b0`7mY1m3j-h*>j! zUe~$ZJ+}@Wpo3PU&56@3o~N+j8%1EmPjjCAGHW7M$k;Ah+FGU5ar88u7jt@8cIx8#k9z-g(mpzhA5 zXW9z=XE8mUp<=5(*c~3QYuE2+fuAR|uT0Cjo1Ri|?{r1t&dsKdq3)w=Xd1Eka+6L zJ?7*}O!`_0jKgEdK3%M^j?nkSbTFN!o+wXH2&E~7q(OG}3{y{}GV^~_-#m3|#@6-C zzx?;ZJ$t(T?e5*XeXl<9)8E>5?XUj9tF2p}8cf>x@i#Vp`v?1e`IC)Q!>pB0dLIsy zWN=O7?0HYz>aM1g{lPtV<>WAX? ziF~IOq^igrB%_M0pNJ1B0WDun?KNwEf2?-q{^rS(U(5zkaWCp2df_y0%MGdo+r#qi zxZ^C`SrqQIh5i})h6ZNQVOy|L3&zq**IeCtovSG4s{XNYL9{Jm-;7hWKNdU*@whpA zF=?hW-ulz;naG-%U?MA({_(n1AL-U}_1n&;d2-b8Qnmx5vpKHa7I^mcz=zpP5YnPj zHMyWa>?JB?#h{FEW3j~1EEo$g8Fr-EFI2>Lw&f3_a;psaD8Q3)4)9bLIBdxo*=(`G z2q#00xpW#Qq8k^DOtkVgHW$tP4Gfon@yId^_q3 z)f-?BE8&JMXc9rT0UbmoSo#0C!b1;!DwZhCitjq+$(4nBj^w6@q_({5;>Kh~qQ-4&AZ@4YOnT38`>DWp1P*@R zE8;mGSRxZ*AiTRcGlh|o9puDb?q1tAlbT0tUF^*vyqM3O+44RY=E9N@?fOC zJ94qWKRA6RMR;sTpP6epj;`P(o7K0L9Ee|AHNbG0tiZ7>L3MD^(pklaRYfZHlx6y| zs$FX6ad6y<6y?C6Gdz7bRud%}0Yqf6N0k=#!3zkKP$k~(xrE8XI!oebVs$e!u8})( z*~J@Wrw%9X96G%*WmeW*=5|$5G5)ge0o|nT!6p=o?ZwSw4Us-JOAcN%sUlEP)XXFQ z+p>(Ifx}GP`0oV*mDW(8C|qsTKXL|oO10#nmIq_6s&`QaACP}Q@GBTA!ec7}-@)kZ zW6m8hdrX5a!=f@0`}D$>Ws|-Xo)|~y1PXK{v#7*Lyj_BtYStGnwqyf{Tb#;qkkXi<{5CN{h-(RHwgY@uSy~* z5wa-9>S#oW@RdDuvf_*#go7&g(Z~1s3C_dm_ z;!;?AAbGlDUd&pC&&Nv*$qKGnc4{j5)J3G_#G`l;$GxfaazWL683!N-&2^49J41-WSoEJeBQCIng3S#PnP8R{8gqr--*D#z z!v{!38XJ@I&>bWPJY>FBxit^MyNQx2Zv?(2m;CJ4laM!Twh8dLHz?8{vW^EFdIYf` zeU)4uA7RG6>?5%N2Hf)}!}<6t6cge`Fq|m%nH(&}70~kdJ~xx2Cn|}_&{k*W zStF6y;aIEh%?m>@S5XWq7ruPRaElrd$9#VRC!P zH<&)ceHy~;)zH

MWcW9K%_hYRpMo>l?&*9+&FLhT@QBr}6;&CJiE{^^#YSuGQpd zJWh*$`2Fyn@t32&(Uy`I-h*q!hQi+;)k)XZlHMdc@SQ_2rF?hf4o(AhyXdN9q35u= z85iHeCNPsVIff%kSu5fGyoX*GPNO;yXtd-+#;0%48?|SkT(I9Ev=P>cxQk0!O@c|5 zj(9;LMih$TBm;yX1@@teGJOi}os5XbuAjGtYi-PMpgorRWrf(lBP+L9biL>&3<^4S zW}WQ&i1X{FF(f|$8*LbVxav#HTlKj8ar>I8ZPYQ-$$JG8L#l>fWQy>7BJ`m25DV`_ zl&;6dYDa%0)RUqQx#7nSU$bbz=gagl3@W@YXr@bO>@w@yzEx*Vl_xT{3`~%R_mZrb ztvojkaGDrcj3`kNc0Rf=>v8vrs^pQFI=W6?#YNTQCYUbMgj%`Jo5|d~EZ7v6HEFSO zk$z-}vQX)O3BzUmhpca9*XQKFq70`#C)s|67Xss8R;iW#WK0U2vGh)fVi!?1qaR+& z?Y-6KJzZ;ER&2(D%=e-!mzR@+K?(S zVloD2J9Z(5_TVFAMC(^=dcD@`);pcPer*i7WDaeo7O7p!3~!us!2WGxbtIX$GdLns zcF5l16NIgdfoE0LjA?`LXbjvf>h}oW|&yCd4c~*!(wQ8Mh=2kR!vU}z8HSLdZ2$s=Ylm;^2mM=+9bCn zxSppRitH%`RJ z-H!dCAM3bl0VrFNggt{0bwod{Y;mCBP-!{t0t=(jqX@khRU})}oFzpSwq_UhJbVql z?oDhJ{2H0Y$bCYl6{IqKdq!7&rMIi2p!$5mrOpMz(8Q_AD`U?h1A^NPf}u+F56klE zJxjSP=VnMp6ynZu^7U+>h7&PeCN2xRAkGh$?JUe`%E5J`^VvE1`>mmov(DDd&KNFP zM|kL6D5<0undtEhHA$VII8XLa+>~74h!zED2QUy}Xr!l9Z+6~4rA7QXk>4S| zIqVI8&GM2)!tz&i5@8gph@&{JVu8(14Q+<}JV)RLxU1t%AgVIfsf z!>EvNC$oi_-LNcBaa)Secar9^`owj2<}aEOV7Ze^`Nqs_=Pehq$!HEV=qw;t`_>8l z(963UKmYM^SH+@_GhPq>>Q}QGKK+9$Y485$$1<*cNrX|bkl43qQ#!zxgF>?x$A}AJZA5GgFdQmCKZ{( zabPp-N#EmG?rtmbr>}Iyja}th_p1Ht;`X%NNiEJhLbhaqTTAFb2hy~T;CTE8#A2n{B*hI-Oz)X?E_xHRs)_OWO(-|!A2W?%Y zX*S!R$SgEwFZCLNEesZ6GD!1NIcgM2i9_PWedInW1>P*p37*w|8>@%x;Sp^--x|7C zniCEBj@3o~9nB*dQ>q!ocXbtTjD*QM_%8(;?=tjA!(&FFn2@V%Pj_QdWz0>p-t zOS}fhxE^H?Fm(vltTi}R1jK*H6-iJ^uL)CV0Amf??u-2Wuw#w^`zy>7Mi0TB+;++^ z=z{JzqcL@NBnRX_<6qjkFMr*xm2JyogFjv8d$D@x%{^@`qviPxTjwg{f^9U0_>vso zlG?YZg1cwvPFZpN;g|&TfwB2SDNbDZB-9PQ=TcV3Kubkwb7ReGvB5>vLxZE`QBTZT z*29$$<~ZIgnH9DbpIgx}XDiqya80T4$2(Wi#nA!3sLInrCAd01&2WW>5F}Hhv!@Mn zsbJ5pQ-z(U(=zU|!}5eD65g3rcX)&J#j3Fq8pmZVm4&&C5YJnWAViv8vxVB@@$cX= z*|g`UcB#}F>B~S~{P2+WvPVP4y7GJqYc#fUAT_>vs3eb0nT?Hc9rDbL^%R%#h33gX zqBDH2H1fb2Dai4^+6wQry41NWhl7QUmzLpInj5#ytsF=UE(-7Q?VQVc>5GI-bnz&K zybK+3R^qPF*6T#MgX{=_s1mOwJ8&RI-Q0V4pR5*#pGW5#S5BkWGLY!sxyQA)pliGB zl)nQ{GfoxWyHQcF=gdmiuDfloC04F<4UZN=j`d1w@Sa^82|6P`nQj9dHcu_2usvQ& zO*npU)fs+Zb`%&vB4Jk@QEy`hytm->QNu29MbLwU^Z ztIux7HyIZvb+RQdF`4nk=2M`aFMlJqE*%ijQ91ukXvPTl*;o&A)la;^q>$$$SjP2# zEU8Qlm`!mFS+IJ%GA~5D z|15g$vOZ5u@J$J0>84SVnL5zev1V||VN5URgAGhBNN8}NRy#R?Y2Gl8)x{$(XZGDb zc{J^{LL3PDa8;-wcrSk4E+E~ar-Uha*Dy0CyvJnbN5wt3QU8q`9bB`W&HxDWD)mo` zA^}Tyq$qNzo2W8|Q?y@~(!`IlX}LWTd0u2jAnV~i4P)%qs&i~S>Dm`ytOG5g6a|g@ zWj$6oA3cNCaIXHKD4g+UBJAA&6;@@uv4aU%6{LkJQ0@%u+~wCBm&RJEvqwF@VBt~< znr1)W-Eh|P3wofaHM@!DcwlcU?AF6Ydq-pPyDFAD3%87q4VBnjTTKuC8P)Zid-eW? z-3zK(cbAQ9kcy1ZXpHR+aqMZ6wt=$Z-0MQqnY1Iwu*Bmt-DLwUJ+COu1_78eNY$ zx-MM^N9_LTwFhq2-S-TFr*W*mduXt6IQuI&9gP2-I&)hdyLHdD<^%cbI!13r=^*B; ze}*N2b|g%sNiM4ZVLBYhO$?1U+rLK!@2WEcspwa62cU)s^tjs~5uKxhZIB3*9BRYB zw2u~U*@JOl8lh4RCmnS4l=#mLByQc~NT{wa=-MdpDNp3@8M?7?rGtTsB*w<9G#GoR z+9%KpqgXuK=`MO>Y;KIJPH)cI)eq^2`m3&gEpgY~vXzbk`ngm7bInjP60uYG2LoX$ z1E&QmXf}^MU$fbEip3S6@-9o1jq8>y;2={%m-Y%p9CcrAR4h+iICk~M!j&$TDT*+% zQn6(F}^CA}G; z&T^W&eCqLqg}H#3VZoMOkN#TC>tLUN1+gr(#8bKgim1>>rQ)h0O~Q$fvmo1{Y#@=w z)89H8Q}V(pmJrXcMyx4Pm5%Gm!Zy*rRXxCtSg1HdOp^=cuvyp5A8Tb}oftO;o0P7b zemKvuE@@BTLxdi9aVvy4%%;N`Z&yWuzi`R`pj6e4#alXlenv@{;=p z05rQ1Y;_B)CR4yL3UDOeu|>Z13l5gIE-%a95O1jrv|g*<`kARE?edo8J36z6`ZltE z)9Mbkv-rIj}_SUxzWn%ZXB^_Uj z|Lm*$0lM_mvL!=bOArrajF_HA|5HAj#S4<4(Ce+k<)y_#gL8t58ftL3#JBTu&D6G* z>lN~l6{H}30N#`8%2a{g=#I1fGH^z<)DL>%N`n*KNQF=>0vYXH?**^lnSA zob@hvSfiZbde&(8``V)$xCAS`_nOWobPtOI=w2;zYL}zLB1HKo#x9*#H zz0s}vz{l0oJ>X}SC6l&$Vz4o)H2yP9%`6Mo>fIpkArwG#VD^75o zYLWbI{a!371Bzcl^vcDW*IHXp@yAR-(ej*cCx1P-2(?;3t`KN#s^67###>h4xR;&Y zzcInm4$1@vUY~HMMwbf8g;H6-3y_2aoKXMP~G6v}2uf zDp%~1q6Lwf9bB|$c<@MY(e0Y4=S!CiPi+&`PDr>`;K$k1fAP1wLr^_GwMD{|w#i#a=)X=QebVcuzfaA9NHG>@znP^ z8ZCL&dD@yO(`$KNhtQ5GH8hz4wG^C%AzdPKv}5!o4o@<^V+DK4!7UvBB4IE9s4dMn zI1KlCG`NgiAECKPTjX5Umpa?dCCto7>lse(C^%GEu`MHRxQV?8%nRPhL;a@Qn6zRJ z_nE4|LHz&+MzvMs;QEukMOSy8sI2Xn)i<2(>SWaM>BEPwbz-9?2Wm5M!KVw3cx-+G zXXJo0oS}C)!*0DLa!nu828;A*`gP=GX@jxY z1wF+abK{5_0Rpx1*9FQBg9WIN$|^z9Ppi>q46=08G^`K<>5yZNRCyJ+n9#T-601A( z6_YJp>Co7)gy%0uVJJjqI+<{j0WYRx>#NxeprMc&(HM@6#_Jr)VFrho@E!b9pV{T_JPM#76-fsumWLjI{!v%`)0Sv>EmXArGG73z6fk{TbEwnE$ zL|HboVgS4(QUct;F$8nO<9)(&V^1P-_@1v>#K+_ zstybhbc9c#s>GdLg^S#{&$?UXzme%ajo}mL?z@y~U*qG+Hr&Ar8%yP;P%d&Edl|A} zpuKIFRJY^`AeI0MF!R^k zwWGoL;iP3w$8vrH2!1cWoyf72bmtEEskqI|>B_waPcFx>a&R(b@gds!kO$3lHgj2sP*0m#*HFUXOOVKK;t!D6 zZ>8e(x+5QH9*3T<{|4%bom70}ymy*_@k=szp&M{Lm@@j7 z_3e0p$tynxN)MRvL=U>usoTOc^--rjEi#~wc0Z`p^w_R${q=$rgVrIBUnMhgIGYB$ zZ~L%f1+0Lj1&0>RWSt?WoG=%fzAGvQA@_$D$3cF_hm zFxX%|rzQ@wnigq0B6pxbf0#X&iBjEC!+3&#F;CcRZaL{EG4>>hCz&{6)zOz>Mqp*) z#1im47Kg42#tFD>4W*s^IwSTl6LJ`DFj6zVz+B=slyEM?acX?P)LkG@AhVM-$<7e{ zSm`~_YU99m8l2z4tR`kem3#$x!v~g&-2T=bqPkY@Hni*OdEPi4GSEcTEs3gPMiz-7 zdlOF{C*Fbc7uT#8wM_G$k6WGoaqF70^GG0hCWM4$vZ7Gv?;|ml)T(VvDOfntD=MwT z{jA`5XuQ%nj){w%$sMWI0#-dEGN${S-W0uFzhlvRP%+*f`83$5ysIxjg)~M2Klzm6 zprGF~1O{TmtZMiP56Dpje+XrX{i^vd*52fXVr|Drmtc}`UKpZQ? z^eOh<(NeqYW+j3mY z>cs*LYMea@`KN~EfhVQt17vz%GT+=oEid`rWEkiAu9r9y5_--VQ$~5xM!GuBp-pNJ z>8D7ofg(I}1J9o4X4N)4@KkKNN4NP}Y&qe3?$CIdU<^|)%ss!uhN@LX@pda0e@?o5GwWQi&67{`R2FRLo>4WGQojq}AY zb_s?I=C%{(8#y|H?U5J+mVnpz^s*>&wLb& zi~wdAv(Fg+$Ix<;uuGhm0wy)JpW3{TQQ_er;|nANef8A#6TQI3X#^sFGAk$DXmAzt ztOj^zu9XH}boRA`{*?89pnDS-aYc|*Urr&SIAz6Mb6j(5k)1m;m49?|Qu`6IyEeIJ zXH9F1vWZMi7?Ul0N(BlYv!1e+TKw<&JB8C?Y;)YsgjbNEB zU*5ZAu6<=Dv%aLmf*!MWknB3EoS>z;pYdZ4b4i&jFq)yhj(1nWi>AX4ql0e8C*GdEb-+jUP1k z+GCuW0SggqN)Vs01}oMuu=!EoYH6VRhdIUq9(Yl=6owi~LyMeErQSjIKs;PHgYQo1 zO_tl^f7<|qhM;UQQP%Lg!~$hj{>-nNiviwgVu53*%WZc&kvMme{^?S!X{mPjdeO$w z{?^g{?D6eM;g^dd@26-@r>tCaKF*cq{^la@fGaTCKR^8PGVSnk?QnefycI zm)NZ+xIKN?)s`RJ9*2i>*0i3;`-ku(+U1_0^gYu0q?T!Ia0upk;$E69DM{g>{k~hjPV?zX@J$emp^zpdZ3=@N&m+~6+h)vwfDu*KnNl$h)< zWVwif$h3Sd=K_ZQnJf75Fn2_TJp3c8k}~?YXNbGBd@{m5u3eLR9#JMyN;b+61J<+_ z4h?FcL;>iSxqkNHB25L5$rRhc8|y}CiZR)H{^}Ebh+GMCOhV_mYly92U)I9S-QlrV z{Z2S+$Ao%TdCrWfymS)1TM$NEu0CpqdGE0WVDxB%)`&G?j~vj0T2B#Rs#lOCWc6;A zU|w3Yu~`^FKT-)z!=2K*8bL@&`N$?cfz27y+x$gVY7GurhSXH2N)}|-Irsvj|BUu0 zc7q<{#G)4&FN);qBijE9#YPcz-JHExz!!5!!{Lo9MbNF(#tB6$Dr~hmX`)$nL{dTt zZYZT48e~de@Y1tGiCp1^$Nf29pI!H*bY)TA=x55CZTPhteA#FEr5l$i5KFl0bPabY zxAc^g88C@6k#b>^87PcUlG(s!z%RlBWtsjZ(c@hu3II(BlrKhZ!T4MN0aBv`{3uclZkk&~N z8%956^q4S4;AV$z%K)aL(xesYD~(hnqfO|<(2L;G9WPoAQo zKso#B5itO(;D6`W#Q8kP1*jr2;*3m-_)_#gi>fKa(N~k3<<(NDJ=}UYu5DFPw>twe4T3<_ZQH8TG^1cx8gy3LXzEhvB4_P9O+Spkw zm-NB77CyajJ&G8> zqlDQk`JSbJh~i3K-ztR9+=;~hmX*?b?-dzF795X)>`{g?%d74EW zfKDua%<7UMF*0H)?nQ5>uco8UoUxbLLb8l^}r5n@E@K zhHnfmfbc2J8>>fbJYGiR!;%O+ye&)_7(~*jV5!8@LDO0jRm%aB;Tj@2O30F%Jq7 z^W^*|Wobi`2aadf8#$h0orl1EAs?&3JYjy186?5RBFozX(ky4hM?bM%F}%&$kHm@z zZG+%*>mn}%V^@jdH9Ln_fv;8h`sInrZzK0Ef@o7OPpodLvMqK`pxhCpZ1)DZE({JY z=?cPE0!{q1s+7m8p&Gk_!Td(BG3lfNtsJo7QPd?Mps{~J_ZqvY83+nQsLcU&ewA%ixu-%aGB%CeRh&7+Ai5#-H~3)J$s7w znqI2LT+Sy!lgMPLPj`pLO7%NMk$nA*om>jfd_(5^n@}s~8rwU1w+wsYGBWcktK$97 zMv(xXId6q=dbB#~!AQ|nebc*|Tm*msM&bCGXTi+4Aws>1e#r!8CV^9AY-}Kj!G<>) z7e=|J+i(5$Td&L#&A|Z1sMsX{VAAyCF6v;;xf}G7@;GlzZ4Eb^Mk*{)3vHAAG`~B{=Ru` zv&T*$EG2xZSTIPapQF4A=4Te)xCAGEf@Rt$k2&L9<^hQGr#2f?osS4QMp6H97C^yy zDTj`Y;6>qW27Ri^;8KDu31`@5^2ic7T2dVm%JF2d(>a@MeC(TD!{D)TV{5 zl{zDB@Y8h%yv{(D=Cy^3ts$^j`(h*iZVmm&mS$I=B@>KFN{sq#zB}@DKia#8;R3{3 zDxm22B{QPw-ZIt1V`F?wFRh7mlHb2tPY7JD7Yt4;mxK`(!-pr62_(o^p^b~@&xPTK zNSx;vo^J*ICHvKyZ+5?DzjF5W8}g}nkC=3PDd8H@U9`%baWP6=GbDH4W_ZyyWhUJBoA zEVb&_TkN(jYxwX2o?deQ4mHX(!B@V^ENy;K;z#NF#NmG-L+ybr^c5|X>%99On7U;8 ztK1YQBeFnp>muWalO(L`K%N$(U zeHT0=XU-?IcNF;hhO6Q;qDE2XFeu1eYH>9C%Sn_$W%W_{JJC~^YFLYYL0`Wu!`C-F zbPd!Vl@++}8@{@#=5^M-xlHoT;grRB)?qP;;)s;^Ib;7|kU{vUA@7EbJ134$s^h#) zJzI>YtS8bB)LG%&e^{9~>!hed1&41sTQ}E^k9)@2Epxim!pXZyb`?gurY1WaNXdaS zZ5(+E30k03|G70X==8RC>z}t2Y1_32sl@TB(u?4)R%Dsvyk<|7$_RNfYwDcEn7hY_ z0~j|`F2}5;>uD_Iw6-?D-Kx|^=tO}Pk(JruO1;mi`)Lym*{;@S<7SH43T4E+U9od9 zaP5XVDHk3&6@`pR6`O5#n|UzW$Y%%?Wf$1AK(Ri=4PkMAk!xg}HJaF?{q?h)R>dGK z`Qw?b35v&V3n*TrDe05zje)0&X8dO+BSGyL{Mv*i3SXFM&6wadV(d-K&@ggsg|C38 zA+x|Zces!n0lt^+qItovdNA}u^B^|Ff#l%fU(3i=CZ3?oE*8}oh(>x28tbd#-KNH4 z!b-(s+1->FZ#1$zJ>-mgCfyT=FY zN~|+gM!k&QB70KbM%*ItW#*b5rj!7~TWZP_FpX|BMHm^|EKUw$VoD09v|J|jlk#1Z zecBo-6>4Y$rx}xd_=-vO%WCeeK3x@mTq@e_Yeoh`zO$OI-5RMYbq0#p>o+snqsbH) zjU1cvLm(lP>F!LBq$~64()U){pRg;lN}dVz=mepog@XEybk(Z(wO#obHDq$h`Y91v;Tsl^Gtg!*Z-wWadq$BftG=$tdtYdjO6wST)_ipZIS!2 zkxO>{{@F+$5rIbH_1`*l4|sNZQ=msrJBDk%!+81sul&nmDI@3O!b4GJ2CsWV{mw5M zH6WRUi)Xj>|BtWcf-Qr39BYxs`CvRl??k+Hi`-a9F_jDc?Wdq9uuzTE7%3_&gTrKI zFs%U^jBI9$BPODjUL>c0__@qS>uaL zI)b71mu`&ur%|f_<+#jq2HCdE-xTeuK=~!P)j_#nHws*dnw3m-lwo4%g^aB@e-SZ? zF(sc0#Bpukpx)X$3l>29-dXnXMOn?zk4@_H9hoyZ^SB+&k^K?kk&KnzWCwVEAqRle zJszBA4?;)yV8&WlC!{&n9KH^t17?`nG9vC-~Qny8XRRSN-oV|7`l!p9Htu%lMi0 ztw;a>`q8&k zo4;p9;=y&SP0~uaO$~;4W^g{x`ncuvu4Xsl1_M*VnE_7V;8;%i z@GLdn|D*b>^F7raBkSV28ZTwZXr>5Q1GRZT2CElzW$gkuU$A0;A0wkHYpBZKn&~d{ zc5Uphu74;|hA9eV?vE{Z*YD;Nkg?0ZsHnKgaN#+=Anj5 zS#8&{z~7PXU3Vrkw!JFv8FJE}0!0%TGSn?bVj4Z7XeU7aqAp*9gC+{23hX^9g8j@4 zxxG4~n|evGZe5mM)JVHZ%ocXbG0PMAV$x;H6LDM=s}Bz?lYCUC#k&(L!O3F!LVHTf&;>-w5XfX(ZLEQa<-2!?rIeOW85fUk~8EXok|-ski`?l(^-Qx z%ZrrGUFI%p&Keqx0Tsw=?ro?1YUcgeP}ap**VbNFO=;l7gat+xen*HBdh@}U1W?1_ z3;B1m4l(gC(r+x|nH5hL{cS8*rc0~pKS9d7OwYcRsD)cJz$f(8`h!^gI!qR=->p|_ z?oxfYC_HA1yrP9Z$b<3^qr>?5Jn0NIk^n^iMOihZWANGjk;lxf!dO<~LG-}f7Dt#E zT=y2|suZm2wRZw|fx;tPHQpf2HyCk{l`3w{Fep2%QUTd#dA+_=|_$ zq6h2Nq{_fhUq!xas|==bNT%uae5CQRENP}l$b3G+fU$U>DB4BAGgV&ccRZ0HCBV}o zouS_}r6m;I%Rb|6d*}i3Hu>)r^;cM3XJLgIzM{zI!JutRj={O{S(Br{l3*35Yl`!dgiQeO1$w~Q=GSkcf~OY9xLw~F z=qPCDJl#>?qN9i074>h|3SHsMB!7RP<68gLq>Pmv%eTeXbw17yiYoDPlnAo0HRi&u zs6n_j{CLKxa|v~w&keuUJA9-P3=HQJZsP!BLl5jZs(a0njhGLUiDE8FXdDOtOWLu{YC4pW2mddRNrIsmZMH-F$U1GPKzdQf_T1pgduq z`zTkKZ|z2sQp6_W#pbUtFIfcGmGZL7{3hc<_#Ap_`0%-eTf=WxvI9QPaEZjNLe22R za5fM|7n0ZcoZ<{Q^W{p}p4+7|nV;!+?Oei5Ue9zD6*U##kCk&~8Lh5ZW|zu^76JV! zAn*_*9(yExN5k-(cG(c3LoPNMua7A4+4c6U4Y{qecfHM+VHy}q2$&x?iH3}B{Eyyp zy@KSB7QgLn!!FYVZ{wLdPyI2IQ6enSdb!z@;X5>4+_g zD0U65-H{E=2RIF!$!K{;ywcowDla9lLRxMMjBH#Zhwv3%B>MN(AEfBYqfELk1t(;%5r`?wn_b3aL|?x`-!yiF?Fe9cI|q)2s3hnd~&Cx|1F&`y3q~kk;kt?5?acQ2IH4q0rHn3$-5xh~Y_- zjQ7GF^cvWfXPAPj$}uQ%43s)9jj%%-1PLp%aa(VAyZ>A!5S*U><)d`Fa`pN4s`6{{ z&hwn|mat@z-HGm^$SqU|gT8GIA8>}k_RT(L=!ak+MD&PB0R%zZD0W7#n__Z2-E7AbIsgPJc- z8_)N*SZ7qfv}fCBd2!w>A|+fwxj6iGoEK{}{Ig$ZmmL950t`ar;ftjF-sD)KXf!h| z6QN}GTq~Jw&R4K2Bp!^xvYUGozKWRrqF^Dn>wpCzS4E&l8+V4fQLnTJx(|b;QFg6# zW5^T`nWhtGntov1B+g|M=`rKnj-sbFxz>#<6wA{?JSF^xtDKRW;hs`O;=4rxshB1l zbp}kxo#aqgK`zGZN{rQmlKo-b7(L8KKLL zJZQI7Im0KdCHg)0!6*l}u}4K^@R-j(UJLcu!eh?R0pJMIoV1POPA(`$E`qV5D_@(a zVaHAc@oRIZh?5f_2CTJ4(!i;Nc4QuyN>4>4B_NTeK~g`<8N#lb_FLXP$Fu{AuNHbA z46}@BrYt_#Xo+~-U~~rQR(POP``&;S ztfb_U!bQ>JF8hC#n8|Sdsxlq)UdFMi27u{c(nCJAmgOhir|NTk&gV^$X4*B>XWCaq zH0q1MS(dVfnR`S#%HuwyX3Kb@ES^e_{9JA}#H~J~dIU}0B_Yq2~%u9lC)E zqp7OR;zae2D%0S5py;N`1@9Ib82IA#)pKvy&oQX9-M&Tk7D@p6e= zfrc(`8{pe4_R7~5%B624GB9&){h@NX>wtD)|8CSnpHy3Bw$Iq+uuaht%aiSKzkjz} zt%&Vm0;|~~guzwJ`^Y_z#F@|fA?{C+3`*{T&6L8?{`E;$<%_PO4k`=5S4WTTn`AG9^Nlf`O1baNBuxqGoU=ESoA@@|Nu8{Aqk!(GNv0Afa|P1yN|g`HEQTfjE)A%G}l^ zLzrIRFd=LXq0w@-r1Vyw@^q~P>l+)OWAGaZ7PR=o)!QTrKZz(@SSmDzkT@l}1geNT ze?SUg!f_$B#c&zfUB}P%H?(i>y?5T@Ta%gf9-(u%b86_&M!UgCV)8=*2!)kPK=x)Y z+{8gdW;fUi7-gCn#`4M);m`J)5L`P@Qc>)x`;FYVVgdF7bB!WgP)NW{Sv$_;RwTYp zKtY3`u&qeH?b1i5MaE0@q3&?MHgXnu3=xkd(pD51u#?6%}LD)+=(g@!A?$`vVmY9Kf?XdhJvaoP+%s6gkeG;?HPuY@yJ|1}@o zL?nzD={~gzC#v0HIOXdBQ+?m7aYGFoxC&2 z)D&)=h4WEDTjJQwFl7a*Fuy&TifYstFJ>bk`WOJ{9o^BiVmFX60kwq@0883q>JoS&WQqu<`{Vh=OPCi8TGvFDHB=y1z;uD}M_+Kp zFu}n#>`v>MS5%oj>_%k7S`-WhI=Wq#!r^p0fc=i6x=n;#R6Ry|Vdh!q!PaHZWa9i1 z>BZ9ioiQFXI(R#9sL^rY<_1*M+fNT6G)aCi2R^r=MayQD7|a5kVqnHCR?#t(tD%l# zAUQG`#b9M1vtdazigw^yf2=+NcaS!|+HKeVPNpLWABZqn401Kp6HkvO++Z)15I=$; zR|Y3Q3XdrnWYqnP?~N!Bh?GEb7=YMd=b6)9G$yR`pCASV5pow#3=RXLR1oc1b-tV7 zx}^;6TKT#29;2~u#L&(h0iXv-G#3i?z(mE&Qt?7Z>bb^XPoP;J=nm8a-8bsc z$E?8&z1LQ)`KNQnYF4TJms4lun0 z*QbI(g%2@MY#+)=!Py5{emRj~5RJor5M-Q708{sH(_0z)2dl2_+&?&_DyxcgKNf5lj~=bPJ^y7@Xq=2b;i})U{(@jZz`7&sF<51a zT}~9_BxjtIsadMRVJrVN;z6m*zGwl5h!$}WPPkvcT@Vx=%9Up& ze}aiN6HdzoaBm`~O0N5OgmomPjnS)EJ;bXcY~cA|8nl>5~Ephq9E!AAQPrBEiC zn}RyAgVtizn5IMVo}4Y_7@)z;sy0H}YE2uYNM7(g%`_Afcd)cke&pO+l=YJ*Z=_zXhTef>TTKE6ifBa+Zn=Df;Lzd=5?ade} zz$xwwJ*bu;4AnmbCW%trh+SSKoy?}in`iX`AgXXqj(HZbTTyNgE9sIQy%0ycl4yH2 z)hAU|Z3!}^+$SYXaadY`9@-y#_fTbeM{3W!nHg>88ZWKwVn?Eo4ln+Gy}&VSPPc80 z&9kAbdv-7PtKbUwGh0AA75clJ=bWe$FcVEx!=?ii&_(fpw-&6)xuP$rA;%N<(l^BR z=D}tkAE~tiY8{Tu+^mn^W>t2LqW7#M%nH5KmMxavxk7eO- zdP;@>3T`&}@m_%cp44RNX#x<7UwnY8{?nbd%&7vXN?wX5brEK&RQ%K9G} zr@$8>8D^RPXit?iV5UtqzYT)Ng zdTxKDJdJ}u{iMs1MIHfSn-@bH1utXdS@8|iRmAPw{GP}YQT-d7y;?cRa6>pfPvl zOH9F8j>h1d_Uk6NT7C$gDA|bwk(rYcD@<6J$5gP}xpC3YgGa2_G!c-hbY;wVw z&J(2%P&&f6Omg6Uwx4(xrOzxuQlg+h0J+i(?n!JACMP!cIh{xGU(TYD=LbP?PSV;g z*Qv%}U`M942yU?7y;wzk-$R!(`3@{*z$0)16O)Vcyahi~Syco!d>6R!`vLCuo|nJw z?pKf$oVIirHcC2DP8bu1GT~8^FQ%EJ zd>c#6_WuxbYAQ+{xK|ZL4)Z%iV*9jTMY+5UnJ~6p{WzZp{yV!Jhxr}w1N@BTDNHQ7 zY4*~y8OmI8Cc!xqNEQ9dpj{vpb7j1OY%hY8{cMP2rpD>}6Z_scvJf&I?cH8Fy z%Eh2gs9V6Qg3pJ$#ux<^SuuH_;GmUbX%HUlJ0y-r2rq=14%>0>=~|O%7w$x?CTixY z1xx*q5K$-5gPFXcY+qo`9`UNV=kY#T7N)QezlhaQKjE$7w3(Or2*bloz!RFLa#g%F z5_;Ae@ug{@Fbbq1u7)k5C=4?NTSVwUu-QKBxA;n4;HMxb3}CJ~`k~PDw%}<=0n5CI z=2hj)X^iPZ0xxry%rH+BQ;d?o%y%|+DXQ+c2&xJ4q9Km!FjSS5T`xZNBy~bg z$fA!}!)f}r0u8H~$|4hGj*#Zi#MCqCN?clYJ*tUq-!U(1N1I`Tf!N)s57|puEJ)q> zJ+}|1JYj9JqfRA54>RTB9R`^t6{w|)Rk3Tk3 z79pD=L?fhs6#6?_-Y>C6hR2lYOsj^Dyz}59DlsNXSO_YJ;oZ#z4vQ8VuD9v8bM$Ln zyIskFpR)?2O6B3@Cs#xsWDrK~zGK+mE$W6!wF-9E1m%-s%%vK=zX5e4p`pUuztd#S zQZSho`BbsZY_8?QTf*vrFwGSr+?*Wqq0T$LZsKv$=3{UqlEER)TPile02loWCSI`}&)3@hs87{xJ zmPPO#^kp>IM3fzN8=l*x!-PG}P@ca*|^Z)qroOj;s_}M>TgSthvIV`=!*~c87 z6-f=ricJL!C)qoa7Fi1T>w!6VllOYyj(BmZNpjY$Rqgod-q$l2Q@gm|NNq{Q`N?^BJpe zMdAhA2>uBxUV2guzTb%(8DkS3Pg;gzEW!DEEhPz@RT_NN*q~I&Lwwal{^|Od&az~4 zy_n{L)xDqh?(FV2-RjS|H+J|J3jAqAc~3&lPjqMI&df1%4<2?>`5~ftVf8ZyEybRbWyo1YFlr?FYZ?ip(f zyK6$@83=^w0ZTXln1xes?rx2BtS(rs$d=J*d}G2wFPuqtRh+c`!;LpGKSvYS{Q5d@ zTK!uU>(qa%`k1#FNDcE`5Dn?@w3uKG34P@_KQ5D*v+JcGA+DFqL?>juT_4z%^S&kb zX6PkOX#M!5wFfI_WMpc3t>GNnIT82D#J$E`DvAL$M@ zY7a6Zqt@_0+w@3mO=R>-UhSvzmgTLU&gL@BXQRm;`KU1`TyE1wLgNQQ#Iue1P^Lh* z`SOL^j1`U&obF_$nwKBXzqPL76F|tsH))0mnV4(&F&ljvD_SGowO|r|ZZzn2StW+z zv2JY=3Pm+Jyi}LWV$%n#A-jGOdpaCL=Dc3$bDumGXQ3jgDA1yJ(>QRBbg&0W-bIbcb7|Ps{<^n}iOlO<-!;1bDX<0YgVs@TM zF1W`I`D?D?ro!ZcM8_ibwmW!|;ahy6qW?Nx8y?EMAwFt)oA?HLg?`2GoqV?cDy5ce zzD&&0o3f7F`=BBbNhM9bU$@09YG0C;btipVc_OZ6%ewZeGrYGBwJy9B*z;0hX>xaF zP0Zf@z@E{9{=w_Lfjv9$d@Wwj>mOW^S(u#aDlSi)+x~m+9-f$_UQJv%bn=rl`TLSx z!uR_}*HnX7z@=VrwmPjock2N8WJ-4c1j_h)F|9r~cPWyjE)7lz&(Z>lMAPkcC* zSiF1b$iZ9Rs9R_Yn6io5>7S2e>0&!mZncDOFVY(gY;>sSw|8b{eD}> zlh=K3@W8F6zKy7M{?p8BLL}l!`&(?Gh(qf+>kJ-9qz}w#U(y!S;QQ{G!bFOFb=3z(^>!eb1C&^x#a~hD(~+zolnDrZ^FI|8)pUVhHG`d&<++_zpG}4wR!*6mDsAvr5<BSyti#t;d0T% zpsVJ~2$;!#Y+SprGL&ScJ?;t}m~!(kcYiHr-+; z>B%pp#k`M$zZ8CH>1c%`Pg45c{PgChWnZd~c{1y*A^A4yC?ib}``KqPi=x(=ueKq7 z&NtRO=;#iO+ap7Mrw(vHCrV0M^h$u{4A zIShwo(-R&?6iy{&?#cbNZw-C0vDj#kAAOOrS}0ePSTJ|fz8~!oW5koGt{rU)*YYuA zhwNhe&&Imk&hhb{)qkUpy}=+A>^dLZv+F}=weguQyX`$V-VB$+6Edzz+DUb~tRHA!0BaSzO03=b#&kf)+4`p(j+c5xanGChuj^bZ8a~Qf z^sdWX6!`wA>y+cjVNT$-br?5nlbl}=LMgW!#{5KnVC6}FK}B*Uu$Bcdy@Nf2Db8TH zJ5m>`MLNBUYjnT90V^aI0|Vw^a?_E#DS=WUGsZ(kKK$EPWqZ051#IbN6HyE1pbBkQ zKKXz3l?OTht#(h_IRc0^St ztg_Uav$2A0`Ltjnk05&Xr-CCN8X)=4q85sQro!jq78Rx~c7#2D^9{}wMr+a}+OAg! zU&qimFRVOCt3cG8Go~N)R-`v-8sE`>Fm>yD)hn8R`SHiy)vhZ?H*J1p_UzR5(jT^N z{?mi|+J1B9C!VCdp>X}L|Hs86pS=CnFTiShL{BkEh(|lg*~T%2z&JZGQM$yVjgPO^ zYn`E%$O1}KG-f6zZ8CBlKryG|63M{>XKY1dB+hhV_ zaGm+<-8GR1JQfN6ubEMpeJ^K~zCMc*EZ&icI0xr-jXq%?e$|LeUG_VAww`evs z`2R#?h>>4&p0~KY1vsJC)tMj1Ge*(I(lv!$OMGvV*mn}=G=)4S6|Z9D&SY)15ydx6 z=`_6bQp*D3m@5GAi@`Z*A0hvH<5@}D$5yqeEb-&;A=&WHp1F!|jE{-YS3QRh$*9-p z&Z<+TJq8OO82I9lUMC5-^XGNJbDjN>_ZP3(0^^8Q06a3ZiVUi~3Y&uxC36i6p)bhXFvd=6mY;gC^X44W zFJrE=H8uopcgEzaVD-H?^T$y9kKato!MSc{b{MI6h!}X=ZThbZ{C4e!BILn~e;{OJ zEI)z{0KG}sRfvFWkTlCgw!HS_`KGHoH-Efvd%?-)8Rd2MZ8jGawHh2E0Y)Fp_Cb1v z6TSEr;|S!LhMa;JlFJu&q79^XIp(!@q}qqe<1@hUJala>0tzDa9)#93-5MO(PYW7$ zxoWTw$E4eS_SeZHyC9#(-{8hzI2?yhxMgNo89MfiVVNx)NVr`0~P?n}J6- zv1pm(yq`dUkEbAOczLmEVvjP%O318rYGSWDprXO%_Jen0{gY6D4eEW#zny2vRIx zf-G`$r>~^60t*XhBv;HprqniDJ-A0h30`;a8wGZjVQN-CQEpS_=TS@)4mA;?hb>Ic zSgf8zT0$ehjz57-j`f*boOmfnv2u8ey^JZJZR|8$6Le;Lm!4tM?>dqC{C(Mvf#i5o z<^eIi3X2?+!&GWQHI}Bp!F@*H>Y?hiOaN5+wdsXG%76z`<+gsE07FJoN)K0f0uD}) z&F+PS^O~~kUgVu{g~|l;W@DXERX@u}ycM5fpODv#4&tCt?kIW4CPRF)9M{jV{i5Cl z_8pd2ePIYi*HAJUrIb;^yD^8@e`Uh8D#nJ&yC#BaK<#7&5>s!mk>coaSrXaMJ%!6e zI1)q}kns@zPW-&McepZU8XI1F3};BguUPbrf@GCdw(TnW%A|Z8^5`h*mTxzeMK`WG zDve{%RN<`o=cQQrB5xs)pgnlj$x+MayESjU=1mDlT#;LEm@02CMO}zXbv!Lv76dP8 z%vqin{^`8ni?Z1GF)giTi-BlmmOF!aaJ=8Q0wGAq76FFgo<9 zD$(#im7#4?jPbJ6aiRT+f>|&=(VgbBES@hW+|rn_CQS~*@dXn@=-l&hBrKjqGfdG|m!QX+_Xh@ae4R!lR3#iw-c+P*0Vm^ppi@ z?Bcf)jcRJ3y@&oupWiXgwhCKlpeRy@f)nm=z!K@Q=tFMsh+BiGigssk6*BE)B_`-U zl<5R=4rHq0SPTd{S$WJ*uW)u8Y8Fx|9#!-4zd7v5xwf{e^nBx`7I*Tg1Abv_(T*l_ zInB9gC(RV+-25@k@h$YRBiiH9lH6%OjFcC%_5*qgiMfc{5mCV7^MDU~!cY;=-bbC0 z4E>@rV2iBINwjJHG?OBZA|M9!E)zp*gZ@0z){0AKMA;ox1JA=8$*;L+z@RRIL<9P& z?+!y&8h5*U4ujX9E0$PM=LuqIlf|YE5s@<&H{tsRtQ5vE_2rd;?*SmTca}pkN_UO! z4E?m`unh#+Z;mg@;pJxHqcUoMKLNIKlK$Mq>L81>{p^p>NRRtobjLC$g)9gIyG4}j zFk3c^xtiHGbGb^i;KI7NtcAzt` zQ&>Z*hf|yY)$*&37sf<-$H=8wc5w$K3*E^0xuwblhZ(wtTuhTGdl}R#a^h$|5wZ5b|iLJp*gD1SG=97jqY;4C+dAe+BKob?kLZ zK$Po)KM`mbq$XjOM%iZ3ma8B&?-uj$%Gphd)fb92t=UG};n7lSxNp#|`Rc8DeyQep zwjtP^^JU~*nJ1qzJ%nEVJ8X}^DZDBb&RI@{IR}M}`VQ1!WKQAABS&#=p9tSEZR)Js zVWp8T6t(Ol6;Xah*-@J_Yq8jlgPAa!0O^;u&IQ#AUXl&tsWQhW>V1E^nd&J`x z%f^y(Y4v=_UXtLW($eCtNB{r7s(oJ{@rP;#eY^K+X-!2ZUp{#{?r8IG-g)Pn-=6bN zl^3ob|IR1t_Rrh1;IAKD_lNPfe)iG2KU)3q-!91i?pxnn^|jwjZJqJfqk)$9OSadz zDyyvBm#il~dt_wS*AaNhstJ4iq0wBY$7_x3bv`(t-JY&_l5>z0aOafu!TF+`v9Gw> zEBu1#WP>-AX}s|p+;Hba!8b_3x3p(po#w5Ts(#nwK_BA@Xyv7Cd-moB3;kP$v%1a> z?Cvh<**h~oJbK8VUOeAQ9}CU5w0p~-?nV(y9It+sRn-LxgKT(?FO;kU`Hn3~X9BH= zhozbuURJCaIJzuPE+l`2>R;y?$3M#cK@c^On7A#Z|1)`{>iU?MeR*uvIu|+vV2v-sh6cKGIh!o`z zQSm6?$xWi1a)VZGh@9aL5J(6)_BXRf5^O);|Nrq?b|;%2FkO;8b}|bjy;izP~n9cNP9L%c8xvALv$ErCJ^t+?jnoHh_x`= zC|IulC@}!h`*Bh zUsZ%XCo!aV$DhD{VOU8Fq4Eg6&6J0bE63Ohf5i&1CI4p1y_Np?|5!Ct0hSZ%rl493 zk;q6Mg|`+g395W8p8rM}a&d)RC|7q0-4&$!fB`(fg_Jv#BW#Wp#$|(?lpwkP5J>3X z(ts}3ImOB+-Xu?g6wX)9_Jx{(Sf$-&td$!av`7a7Iz~C{|9ahdm=2`Y~En zKL3&gQOtdOGQeSaJ7|9;YmazQ{Pv$dIyRqznaIM4jjZDI5i`~`-pHvSrbkC$4)Nb0 zQ%Rok11f2!N=4fSrEGcOXspI@Fk7G$mr3+TU>p#V=PwS3YslnCV>y!`uFt^;;3WUH zW#kM3mqwbRctsE)1E}=^W-~jH->@2mOEeLx97u`9Swu8$7YXLFf(8S=R3l_~grqdD z(G~v#7F|OG*vb31QhW!YUw~*>Il~b@QCI|0mW^(-CoCH!O?x|J0bDitQ*QdnFA%xj zlMg1~T}1{UwUGSnLHEF$TzLhk<;1V%$q@l8PyhOYqUAiVV!YeKBGJ!B25)pqRI$(V_7#DFx2v<47Nnt1-;ZqP}*#@@EUKYFsM6VVi2N|+h=;wh; zGtgf0HH4M2o}upzyrY2sjohhg;}NAKOGG}WyjCKg6Li#gDm;U)TTi4gW6}7jvMS`U z@P&u0l_80rWFmuXkg`kR<${*LxB-Tbu3QjkWPyPLY-mZAZ#pN^?b??IE= zaH?2lG_qWLw`M30O^!iJH8@2sAkE-D!KDGxGnF?|$QOVPtdl97TAufcTD zPu4usSE?SclpxA@k^xmlZxRQ&NRf0iB||*f=WKBxdz{MRB^nItdQgKR+6h!X=uD$b7>p^$uyKCGMlPW9ZvTq}q?lzR0WzX0 z7%Ci&Y#(T=&wmyIL#Y2SE9fpGNKspY9^l!ClX4P7 zO0_?QClzsn`{C;>TZ+1r{pZs4xa1<1t?U8bbR~JCl>uQ2)~sZnVu3l5`lV61UJdvT+D7t` z569Hs8%KI@SU{ou=`bB_FZ6JfV6Q1F2EK<2SPC)7n-D|5hws0b499EH1L#H|xiCR% zqE(F0PKb^77ZtI$*t&|tL@!Y{Lu~19RYfbwogtDxNuvriWF@6EYV>~4x0KQC@B)J_ zq%ED%;URv(mL-yox}N;VlkX#~ZpV zAY;UUSnnDQVN*_?0P~fAcq(Ah6Tt;wCXDz1qu~@8v%pY;%w$idN*8ddkU@@=Eb7%D z6GlH8nE<27W+A2V6I~wk!6>%q6&cyW9*2oiK;#^`(@Hc^=pj4L0TW&(Y_OuZRK$_4 z>#`F4#JXWnSkzTU5X{Q*rA8vJxJUfmB;9=Kc5;$_5=IYs$qC>-UWXmO)+mB8X5e&j zQLF)#)hs&AEh7rpZ@{0D=^;`^g8_r@M(wR)i$R#?4>+m-LOKA@3sba#DN!u>5(Y0? zf^;)MXSj)5NG+nCN=q2gKqLRaVb%zbj!8k0gl^~wqcQ21G%_Cd1A|;1PW{*cU;#Ha zVjz7+k=>_=TR7rbSSmIUB_q#e2ST*|6$;Uiu?0OD)Evvq=6ivFl}fNGPR16n<`+PK z(E3H&5ew(T<3jaGPUcxbAooR}`D7fERooMJRlXD8C%K6{@I8IRK=zCwV@yOz`A8yr zKq$*35ATz4VBQQ6fLmr61+xBto528@DJOz%7~lKXP+s%J%(>ng-THVy zs@-4uM6y6#Y{h8kg2Vte?XYj4dLgb>9A3FlD>%?12VS2id24Kz;g!h zLL_!WM#B<84KFK;RmbN9QhBVyR%Ky1Gag+p2o2rj`Rmot&vo{;Ei;{7955s9{F+Pi zm;dECebc^KchnY~zjJTVZ+EW!=y2!0ke66TOImZ_>#rUAgG}O;0)F_96ahIzn9O57 zh-3N>%Bt+&oZ6q0!iR-?Mb0=7w@=7SJW|PId*z=-onI;)6k%K?dj4n-U0)7P^;irS zh~pC3fq2bDFuJUCBYKzvK~H%UBaCT;t7d);GRN(M63+|dGExBFxJ(32K~?!g=vq-M zOZs4wh_l0t&zn~u&c)IMIp(EZfL=lYxgD^CV$5Mpu!9c>Vh1ZF|WEg&TNxvzW zo9z)Ktl+m8Zp)7$B`lB2ln_oF3&bV5kuXc;*b& zC?D|99dPBo0e_&b#VJMM&?QVHhBLAhDNC*A|La~=iS>NlG^NY`T?X+RFrsRT9{g{` z8;gg*oMV;zWYMB{BkdUH0q9(38q#~8d%SnyJSbyTRLS}o&7_HRB)E<;S%%!M>yED= zfFaDowEKN`Jb@t)5jXfRfDkIeWI)5Bx?jNvHr+r?7|d3|GNTU%GV)kvrm7%5t+|13 zD;Ru6633AwJ>nq}k|wTDB_TcO152XhF+MPOgFtZ(qp^A*2#DwsQ_KM(13y&E<*F|D z4-|1x#LLNp<1o__nkaFuL!+kNQQYWk(<%@i)2&}+MEwsN2HaTgbe}k|q!5HkDLdc` z_7uYI=)x+Ga+T}e7qN8)>UF1ZG)UbP~X#tRQn8-r~i5D!H8foQ#q7s|nb zcv%jJfCv^eBFhXsf=d;#R$ES*f5p^=05GKGsXTa5#4e8#8B)5-zUGK~Nur@7#tC5{ zSZqUVNf+~w?QE$k{XH?QLmc_0pkkPyRyy>n_!(t<(-cr77E~(_#!OVj9_?@npJ=>t zh(?P;u@uyhEk#flg!!7w6a>*s@ObZGAWSKC?Q`p{c#v#>@E#w4u|s%hr}-d!`9LCC z4U>c}m(VJ~&w^S)ZB!U-=E~e$rRfuA)@K^{kH6p{f51zDV*(&fjw#DQIm=4Z)7{sN zm@)pH<*Qxgr>8Cxj((aNj;U!vM4t+jGlM8C2T#Og5<(1(?ub04hMKG(HVjBR6sU&= z8muh96`yPyOIe5+hdyjp#iVhlu3E@a?G~j3~ zy6lV+l*G3slI!Eu2UqArgAe(h4cLaFa7zi?545Bi@PLnmyF&ipmPqbtsxP!fbJF0b zl=lN%^ltUZ0;Qlmxv1QSMlc4OF=6^RJku#m2&VAfl9yn2M4{cSi0!y z9q{c?zQBU$U@V=;kX@FD=4&QWGsB}&2I!!y9D=YIbV-Drvnbp^=s=RS8OR<}CT(PH zj9w06AgN82eV$5^CU81bWsk^@{&R4bpZvr+g;UI*C|n%+7>$g0NY2-#N<{1wOzDSd zeidr4jV!N9w45z7mi=LmsTa7$GR~A$a)e=wZi9(JGG9Z|NRc^!$B&Y~DVh;nDFg}l zrJ$#1%N{WE$Gp%S70rhMJ@dkHoVTFa1B#XxEeD<+P)$SaQ*ZzgK#s&BU?5dFRni_W z4Wo}#$!0QyRmg^+pe#N}94!wF2X@opEP1x*M_}d!OFcX#XM?{F%(1>aaSIl057ToL z`;U7$(_-vNun5z2oXP?r94~5O6Siz8x%PB?NsCEf8Ue%Tq@f zP6C2G&?D|v!2Ft4(6c(#e6(-%Mq0rGrlgZ3{w0;k7KUkwcue3!76bIS0{oEK-Q24qmQw4 z^Vu;5+%nN=*0M|dF3d|N5BO+fX)8crBVa2id)QX2PU0%uYJ{n-0Rw=94z~%mEY+i+ z3nM+AQX!a;D7O~nh3#01S2Ph5hF*MXDFV9@1LFv1ec)~51A078Ab}W6d{O*xijn#l z_{IanY|hj~IHh$$Q9jYlBw z$UGfcJ&&JH9(zF_HX^q**~qHnX1%}Ii&@AZXY?a%xde=1xChYOAgFOjWC}u`L*CcXF5OyO>+yXtJ@SMpY$OVEtP-0Op6#<)3Jan6zJ*(j%YW>M=_N381CE52K>_;03 z+`|@64gwiXkr#$=$pd~=#A*W|nGIo-uiXQ$L`5`AxD*WINr9;dO-R5goq!?UQ_MAmnG$O<7NfL5_%%y<&!W(tKie$V?m5GoN z@}vWjy~L164gsb!r+k^(jjfdQ)D9jY7{wZdW zL~p8)8$5dZENAw(P?o@v1tNa}y9-NefvZq3(}RcP14Yo!=<;ZK0JT17F=MvMRLg}( z4DuC7CJ8hMRM7&d3_u10#g^cwNld_j%QhAmT~X4?Ft?3#*-)yei!9{4z;v}|Xu<^C zqA|T;riv|gj4gPKBJJ~miq(i}N5S%-37{&OpHh%Bn&m*QFrn!WSZ0%N6@Qxrdy3)Yw!Qh|t^z*$Ox=v$y{%KpitD zQNsq9G-xW8ivA`h{bL}TYbh`VYgQ9ep&)|4s7v&W=g&fxd$C1KnxxyKzXM;v3k0&` zrW&pgqgpX^RFHoGgWbV33XAzaQ>Q>v1ll7ifoqh^5|`V!2L<8skGeqo3#tJ;cDoe3 zkq6Vf613tbv7iSG+(2<5PAD0LAc|b+6NsC}8JF)_oF2mLXv!}h8EosA5Da?-1x{?j zE)8~tc(8A;5YYaNuM)<-A1WUh0@N5ddbrL_ zXX%zS^%bWsKHWZd$5#jMth1OMn(gfM=T^zg%ey_#&CqD}IyYn0xw-cq|Gx4-_yfBG z7U4y^_H6V$8B-r<&Ko$qaf_Hv?vzS9YnLqwWDXki{eLEH|*a?637Cv4zkUY}+ZHT@TM7K1gKHW~cQ{0!&{IDZO1^z(_LVnBo__tmFT(E3 z-hDp&j@Ahm3qAEiQ))xawcRnsDrOg?^Pra0>~Q+$*h@FV#tlmbZ(a4Z{vmr!qSFGq z8H={CxQ5i6=4 z!pTnY4(MAGH(In0TrD(U}5IA z?{v?v(mj8ATmK$F<+ahtMh>oNl_z5xHowrWS39YaHpAikx;Hm}wdy%&k*<~%S)Cl5 zb{Kz=%#R}`fg71nW`J*ka|8M3m*$Q{|?C+yXPLA_pe=HjPr zHfEiZNu)8IRCa$XIjAs@L$7dPi!6t7q%1A;;)jd&>9vm@6=w3nY%&DVvz(Cf{O)&e z1~okVkw6bW5iclzklQ+cpWfYrJCe&Ycsl02Z&J+%Q!Iyky3V-`<%rLza)LO?u9VR} z1M~h1QJlpu7yUN{4Y<<(DJf%1theDW=dOK5FTp{jWjFr5p28%L$#YaT|MAe~-joQi z(+?dA??HDdd(POe$pYOtGIXeP2i4_nwqZ?2=?*41v-_^Yt}}X}?k;y7qI(WPhW$T_ z$y$xO?S5+5>B?Jz>?WUd~=; zK^#u#!Q1GC4(-019o~~d6b%!z|L+ZZO6?l>`=~5Z5=);HVYhABc}AngX$N%yTIg66 z;8@b*rJYzDc~#TiFu*Yyygn!$AImTV=a!(gFqRPxE~)9*eYZFgR86R+y;@7;4ytyI z)2=hh#p7q9t`3FQ=>L%Y_27}0VTwY^v6p&F26z9E9bQ8efe??}fw6m3u)d0uT9($C zT|ME|+S{YPbTT|s0vP;PtEVXc+MD~PI+||s=Vqt&)$U5)o8|K^Il_I{8LPVvYAxYC zH+Q6KWog%}3q?=)JaEuy+1#tRE>_MA%1s#XH>jFWvlJ~sMtFV4?jzu>%u@CYc)5U* zdZ45C*Z9&GZOWAjm@#-rEz7D$KOsBV9X#2Fkouz)D+ND$ zUpA{gjxjTQDbZvL(RUUEd*-abbMAUa-Z*WBFkUxgOXvY>r; zjb&Wc)Tn_Bp=PG9;-HqMb#hmI_*3n}R(T4U@>^_!_Ti{tCpF()_1bM2vx|3b($Di+ z@JHBFm%N*}Xody!zhUoz!V8R%Xmcxe>ES)#G~}lxW+~-8UR~=098Cb*%>z6K*lP{o z!yYde@HPAZUl{9p;1uW<`ggN053R}yLklgtkEDm!Cu{lYg~Fnmuijz#4z!S>KGYtc ze|%@{!#R&J!Kc|iDzzUkY6);{@fXubx%_h-A*3tyP7AWZjUo$%b{_#vu};0kP`<-B zt#K7fU_3Nz)K1Jk23dX;#*wjSta@%%Px&9UEN$#$LUIH?_`lhlUYYFO-wX~4^#Sdt zii;hfK!@8yZy)zq2X1YqPs+{{3vgWnT&xgp#7L|-HbS}QpwhGQjErK0i1oO|L!$s|36*`I_CPxBTc)pR=iIZ5` zkN%QV3zR9@NHJ_+gGlTX?*lrgVqf~atKH?`ddT&VTqz}#)0@Goex4C_r}9JQX74u$ z)Hy%dHff-0H&ngb9n}u)I-#8~&Nv7UKo3Vhk2F^yHhXV43cY(}o%#4@4yn>ykKcgK1V&YKgr2hN>x)o@dV%!u<;Tij zmtGB1bsn##NEV!GnVjUe`U_@8j|@{}-)W>!YMcxtLgYtWvF%!)u{%c84b}p%{6$L?deEMJU7v0mBzdwQQpxMGoSal%@xlwn9pr5cZ&C`2EKQ@bkga(nLJbRdBpYl_80}-KUCAti*3n61bRAGr3nDFf-c?4-48hp;6k6XlYAb8-LX>-^wE4EPDAJ>` ziL~27PbC>3&k;j($ro*r6bX&mnq{qrD(vR6R|cCMGq<*nGlox*awaxr8|J5!Kka|R z5d3CuPFD@JXNXjTCME-48XneDPm}L5Jw16`lF#6y+e6akV#kbthQX*-U-(YrTdD$u zLdu_*HCfwryRJpj_g<@2Qo-{_vQx9hUT+Xe>Q|@GCLi?Mv>Yp%l?q;kEJ-n@OSk+J zeWv5!^8BZjN+*TA7 z?+MyY-@#I$454a{I5tW6FZ_SB&B19#Vl24CAN( z$&Z|yLK|8jG^M>CPtrWy*0?C0LT{R7&@x)fGv&2-!?(b%7kscW>zRx&c4@y**E%wpN~>Fn^i%h_=G~u_k|~NziftYr36#G6prbk5 zLlHfXpd!PIJdh!8*|UEOvV!OWganMib^lV$Rg#zG9b9wLW$Lct@K{DSP%^x~HcJ7D zM%}U>(!1AZZ2;z+$<_QH>=Ks;*Iruz( zBs@(ZSYFKhBk0TxREWbtzyVs!z;q^T;ZV$)LI>~!?F4NCBR~gv02gSzgaq+}mq4RS zHUap>N?*5m&m6ojx7^x3Fm)7CHktvNfLnzMLt3e{QwS@>m?Ws3BTo$}eJq<6YKo|lgh{#}r0X_;4l?&Cie7W|f7gBQ+C~`ovF4+;a=jE|> zEp;95%Qr#kuC_YL%#-_3i*=KR4pwhy<-r~CEGj!KFyj{-F!Of?inoA%5F9ou%EOu3 z`=&pDyBZEHBeBBeyk*)15_IgY)tW5ymoUTz)Wr^HY~z-9GTwuM`HMc~G=VBsjLw2f+ei_YgqT6MoW z7raUrn87%zg90_My+e&cjlA?>2f=Blt(?i$yadRfO7b2I1XJiAw!0w3XnBPf>{8QN zAg5h1JEjm0t9&9H4u$Kkx^j8d-OIWF`dAXXxxBviq4c3)jkdber@Mq>kQplFv^Tuw zpkd?g9~?emr$dH`+H!CRFJK^zVvoZ$7*EOUaF9pQ8dmLl+V=psY6R)Uzxz*%SZ*4l z1=x9aRv&~U;k;5{BjZEHl+n+rWM5K(lgeP$WT$nN#FFCOThy}mk93|NU+6sCN_F-U zb^8cqJ;g2KZ*%oqs8Ll&F@@iPOxBqqbJ;7wf4(}OB+F;K$)`xK8i6>I)-eGhxT{KG zRJAZ$Jo#0OL;8P!=ri8BUwuB%{Ol4k8)&An5}UI0!0u5B8-oK9@jXp(W1I|Z|*fZwww9bruWF;{xI6?=3Y2k~GyktIJeBe$1#&DE4PRBeg2nw8EP z$yo-FDj?U!KibES)Yq{-b^^7*q4JCqz4MYKL%`n~hkz>B6E$OJki?BVG{PR$ZYO1* z=HCK3(3#O^?6K7>K1I46+$rXA+A64ZYD%MBW11(6!pwvCv;{4TYMkogWPj<%`l2MS z2YKvX0pH_FPs-(?EI*!;`M8JlM&_AenYTv(aJ;uht$Q3T0ys;6<1WW6{}xvyH{Q1{ zQ7AfWugMxJVv@VBGkTX805#ozh|9>Qds?O=vs{P25r-YF3lWKe5H3CFB#F}QrtcdQ z7-ReOx#{P=*E-s~@#ne&w~Jo>ZtJuE+eQ6rl7IJiI+a=)_S=)kSA1?2{IJvLRrbT` z-3w>WIjUv5Vj9;yqQLh^N7=}@gcUz1B)?kt*t%)b6hNV&dc2Hc8V7lrNS>TH>Q0}a zdx)6qvXYBNtk%Np)QrhtnkGZ+#2PjteK@F==~+wT2;D8chpxIZc&ggZLLv(^52^+J zOr;IS4vA$U%V{HA`uiHq+I6ZNE{jJ?Pvn}9XY3g`Tv4)#%3UO+ak7`wx}Q-tL{$cG zDN;Jn&KulVlh3Le^KV6X$yyz9#|>!J7q@tfj#st>)L5&wzDXzdq^Po5xUwc@fJ{iL zgBECuPchZBv(h8bmSQ%MACF`NGKS5DkOYt6Vkh5T*%NofzO~1QA-1Ot)|p%1&DP55 zXOaBsFV;DY6r|FNO02oL5D%8Pyyl_S+*H5H28 z$H(=XeF{H>@c5mUy z-~gAN-&Sb9+$Xm0G(UUDizmz}t9egil&|CEa&9xmq znM_fvFiRNN+C@1t-X?aWO_*E8(W1q(kmMxq6YWJo8k>&Fb zgyzO~F1rpLdNt zT@~>2g1nM0?+0B^=NaVwo=O@EaOpYR1->*1)jYWOZb)PV_A$EWunYJk2XcMg)?k~! z*63Nttxz+&Jk7O-RU@BzSbT{2u}N>ar5u}50eu=EvySo z(`pPqVRaW2E-T1Ay62|+o4e}(IqXQk?7pByJ70f^Z}j0Pbcf@3C{iNV4b=`o6#K-2 zL&59vZeoD890-KK3^oI!K*Uu}%_In*!m0osR@B#J&6_(^t?q_s*W?5EtU&Yky+>3x z=zt1{sNY_(YapRpOJExf-u{ScBnscbDT$%dt5Y^P6b?c9{}X~oF?yf~L6aI+z`@P# zCId;o8Kf!)rR7|=Mh z>QE8}GsCKd^;-?#E_Cc!XQ8njQdo6Xg8RdzeV4Kh$M&K4CV|ZpSHe*WL-usf6W1ol zGUamsdtd#5&d;D=F`*YtIUaV1sIS#Zb5q0dy_rpmPTD_pdgBWUb~6ubJ77EYpftGR zsNO+ay?^6+_!(>_1Vi?~Q2R%t&p#=NzRO?rKXkIh=2HyM=xt9ooH_~uRCdpqsL&xp z2=J|fHFiRyMj!H=9G?d|v%Cy|=wPSg^x!`39xgBWV4}>&R&bie=*n zUkiaKBMS87; z%88S)P%W%IQFi>SaiCShRbzt;d zXOFP`$D=j&&G6x|rRJ)Vx8hBqvt&|_k+EWPUZH{Mw<>Gf(}e6oCr018Kjzgrk7Sd_ zRZWE@28px#=2BbRm&&^1y#%#kLy|v?11Ix&f&v4{A72}@x#M8M{z;+^L-a!Skv%~% zvDGWmNN!?vt>jHS;jDHomXamTHWCB2d@lQwLad`HFGV%yLrn*J_}fp6PV^%_t9|LV zW=_7F^Ta>|6hR8_f%ef0)PRb)@w9jQ3c@J#%5}V);u`SYxf7Bycx9TQ7dND}t@(r1 zADZGoQn~?am3m8-kRwrdMm%V%xA_aM>*NggyiXw`;bp3=y|w8am&#bbkCv^)wGl`U z^%b1yMeWY$P1LH2z4~!JXL?(o42fH*TLRjiC7JO9DZWyXy<qC*@e?KS5&3<9&wONm=v6wK@Ong+al?}goXECZ z11zz1D#0prFhh* z%6v4~jcI;rZ+q$XRPXl}sGF!_7v6*oc_3ao&iGhpKtC|UN7}2A(_L=O1%3*41!f$v zK84r$?w192zzob8qR^5|sO>$^;*l9vYP;9`FZ$`Ryl@q(HSYdZ{bpk%T2e%q>+;-* zE>|-oGc`a|!gb8z9W-W3-Cf-`^M*i^XXc~_%G z{AhU+tG)a_-<>w$%yrM~=}F-QgcUPJBAf#Temj*r+WErSd#E-HG%||c0IkJ`qY4^d zkCNRzLYXi-<euB@3$@vpr=7SO3VJnPB6H!tG--|^$ckAe2p2iWOUWxUr|5rcc%Z2VbOPxub6 z?$MbV&eXyhpoHa$ljyHuFLlluisp#Jqv8YJ406W4;HEgAKEq)P+^di`>a7wIJ^Mwv z<5=Gd15u*~eP3#76TA1TN~he;9-w1ZN3bQA-QwvMVD`?ZEYO*kKoZZx7)h@x05Z~O zT^zNy)uBa_mK~EB)at|${rSQ;mLH8wMnM^qf8V%y$gck;wPjF73SuU@QG!ZeFouI8 zthkP}y4=dv({F0}Ssg2FBoQ28UZPEjr=V}Af!Rn*B9II_?xv z1p*t&S`73O!f_`H%sEJD|B1jNe0jiW+`EWy4S~Q7f&BeICDc1i$5TxHC`#B|sn(82;d^ zV!)xxrR4Ib${t*p(+ui4qu4=5t2KuVYr;cO%<#v%ZwbdM)Y)qRhUYEt9*GIlsOpV< zWx(!>BnP}{YqSzfmIA~P!j4*32r9=sZcr>d4WKtWuH$$66vdMJ)CAxBa@~?chA28K zbAV!`~i~B<9@rkM=ATAlCt*tEXbPe6s&Inr@aY(7_>m#u#edb zJY^EBEHI$ZIiTGnij>h(b1~3kyg7-rD*qHm1Tuw9Znms48x7`2s}R;h;93{irpgf1 z4O*oJ@F^4X*0hc#a)u%p($!$fzU>-$blu)lwDwd;@-N(33D>OW(kUFlXB2E$BZ0 zERBbYBIdg0jE>EXlNMjSiO;+@CcBfX#vY%GRJa{m7W{M4y3_ z#R_st-*cvHNBSP+DG;*y6RI#_CuGVL&srxvdwGdQX;~^OVIo9Af4aMSZtG-xP<>>`&>68YyC#a1RrbnKQzvKim75^)0?>pcr=rGf0iX@s zX4-v70U=<-J~LK`j2I7=)d4%D%!38>*D>|IKD%;8$P*jW8T_To&Bm8f#xAnO`%+~! zVQ_HTLLT;2m1UAk3Zx9dQnOKt?7Xjb$9EqUtTn%n(tk|D>_G0WhoGcb);p4umtkshsvx4AF%>jtrR#U>HWrezpL3>+VRe zYz?S!V6^Ycc?ZIk!RM5|uu<;vFMc%GPJ{b6qJWJAk zsbxB>!72l(`_3kod1O?CG0nC8x*idg@WHBaP8M*O%HUt{pbBoz{XipJLLuh|SkaVGpl$GKAn(W&Gqe4PI7zIk1^p14{I4*mttaGscRV za=PPGb6aYTBE#vl-qrD*zt<&#lsBznW7$hS)$yiL#~@j>GEGzZRwqcrkh#8m3BX;7 zFfCs4)S=a%nFy4@_k70irUVC#q0A3Wvi4bjL1T;sqV!2DL5)pBb@(RluAFq)#H^OF zkIUV~MaC1Ow};LQzOd;72C|-NYnxrWj3Ld1UBg_;kv!L6kA1&$BFKNZip^Qh3yeq% z6H>;33f4P%AL&gG>Rrw5>TLgoGxnZQTeF`%{;*1x%y_H}M?f#jYD|D_{ve-MQ_Qfz z(gfq(<`0W&786c~a*x4iXh%=ozKg0fp^mGyKP0>#p@|MB!A{uk$X=DD*OPK5`~1+H zEP!B~z&^wkM3-?F<+23#?N2=k(H?smta-CKAHXaFhh3E2!OpkL5!k-bTwA|=X3HE5 zV<9j%!YS4rFrQpGSf~D}%N#BgP|2XcKLGd!@gj)80fYmcg!rd+9~4BdptJ(cb=WT0 zNlrMrHsye85lTLH(3=jxic8G?j=2h;#UE6Gz6s#Pn*36Lv8kK=y=UyHA^stIgZh*W zpwepr!l)Mb5Ws5yWeW$GB&M@M)e~ZEQ{YE{FRBInj3SmqwGW}NzI>a>G4k0;`L=hX;8m|cw}I(!H>7;H?=K)K3L$n_4?&MkDds~+uMe$ z(1}@5qrTPR{M}2lx2c{8uz3H2*8LkB_wHF{S+F~1ldoZ#tEun65~geI)!f>XwE}TV zr$2@E;Qn;S4E;y8k8ICbllM&TGqQuT8%UK*Os1Kb^Gm_(LS=| zsC$rLCreluWnyBsa_7AlZO!W7+S&6}0Evni$d;fs4VfkbtW)aL-MVDjs((|A^T%Er ziEfi#{G_4v!-Y7VTzk9p!ShFU5A7a0iiaa&0{No4JGKecGcW4vp4pZ#caD>7jAQ28 zSFWVPf&3?_cfpBf|E|Scee-~8*2mNv;wC$bO=vxaO~!PQ_ty;l+OGYrLY_>kDYmY) zJ(Dd^^%FngywTp15ggiNz$!A93Apw8j_d;X^oR4n`D5NC50>f9no~y}-Nd0TrpWr) zg;X;CfGo9JKy#Mx%=0g#4?Q>Ihmt-w3BTY*qQ`jKNXwbSjXc&{4SJisU&o88_qj&% zXSX7J@>f;?>rI96$m-UK0sj0I^H-Sq@#h&xuGwr~W;$L%nq}fyGRSK_mOWO#!SSbr zpAy=^(~7;xZvbFw>?ftNu2`*g9IXzC|1}%wb{fhZ*|<>Go;*CmMy5wP9tg4#T;(EV zjB+Wj<&woki>@LMvtqY+={HS@B*x9MD%11&Co+)9Eiqd%1Fq=*T0Qei8`|j670uu_ zROi63Q%;#@X9v$N*pC!3y-s)C7`)Hs`|nt>V};!c$LVcqbE0f>5DsGX^xmxeC?t&Y z@fwFV?F+}evsRixym?i~I}i8{p(INa+u^a`eje?rH%HuF7BoVZZE$CgIW3&NaJn;6 z&X36+9$qwK`V4mlcX3mpW$McLcjn)Dni4bG${zJfOJ~V88`Fg|7f#=+Px)B-UiC#w zK--3ea~96goE+{r30xW5N7!T2oFya~HBM}Utn^@vFIwx^-mAhxg!C&HUbK~grLtk2 zd;22O`j35Q^!KX_YX3%xxX{L1P-zC3d6X98oV(+q{@N7U@UB03;#y?P(iEv97dC7W z0=_D2_J7?UA9&q6iRpMjrS5!aKgmCwr^lKMLzWsKEmf--?s>0%Z7aSJkGBhvYHzHW|?BMO7{WG{Qd=^W?KG^4g=%xE7-&dwR;(7$MheE#+P zwexi}3_J%LEKR6rb}7!;%~W zMpx>a(U&h;G#gT+^|Afu=Hq1Buw&zO*o&|O?8_s0?Rn#6G3LJ4-dm=eKHa;}X7Q}j zbEogXAK6XN*{x?SP_mj1CCT)t?>~lr;rI>+7TA)I6BdFm+QR2V*<}O+PE{h6sP%1X zYaH`}t^V>~cCP0>@!9s|G0hZH{@0*m9FP6qY{$8C>dxoAy5qS{ z7Z#5YE!SYD>u7=YVff^?Pv6;!(Z}guIKDm$28^vAr%%_gJgtQ=?bbrVS_iA=sr4%H zR+~K^ryC5-IWrUl`2dK@(l?1Cu-U)t zc)Q9%Yb!zbw%-3Yy?*u3bKP3UusL;i^I&n_jnyXMV6z6-zSf?p|E=e)b5Nb|LNI*lZzZ? zs#i&M*p*RWSe|&t7<=-wU9;o@xuZFd-fcNi&k%U<-?GOJ@70h0X{D_faxFb$yqMFT zY>-<3hWHh>D?g<_hpU;Uh2u=qX>Z)vBg>{&tf>AH-OX9#P`FXOY0pWcXB7n-)$8az zyDD?X^W4BAd__=Gq>wz%DlMJud*K_~-!u57)|E~{opa#V{f#^0M48MNEs_WiZ@wyP zTcIG%hJH1S>3BG>jV=3LwKXTdwgA%7c-pizX=OI-xi{AQ{0=<@Pj3f9mbZaylsA%F zmHVSQP%EERG=T{*A-lx4ZBl!0igV|$M*@3R+ngTij%Vf7(MQsMJ+CrjO$yTU-c+E$ zsS;FBM5Z19=h(Ai{khi#zQV}c&6B0n`V@2V`hsohRA>K)!S;OnhxKdIt|Xa@I$|8N z-wLi#WXslCKfLECe%*1>BX{^4>$BgFu#k^Q+cpJ?H4P-~Nz;CtejiZRD-J!*J1XA) zuWxLJS~ChW-&36uzWDQ-y(yIL7Nk%0S+0c4xGpyKcoFNEy8~2+bJpwkWbx6H>8#PU z#_VD1-|K$|zq|%g3UV>Ye?W&*3?5m!y_Mc};MP{a3o477X$mX^r-$C$raqkiFhd;ca8iTBvIvG>)|tEg>4B-7T(%K>zotSDxKf|Zsslc9cmd} zNsqHl?>fD-*3!l^bie z-umpf>GxFrT(ed8|Dapbf~RA25jEJ>%mb8Gc`5nD;r^3bd*J4|%k}f!#P*}>=Rc~i zFq&pa?9Le~golGVTIpxsHGu82cMY$@E58U<-q3DpyP(uLQA;Wo>kC##p1F`rNz&7o?PHiFy$bZzEI3g-!Qvi#rz9f2^|e6 z4i>ob0817|y5C>GcMp|ba-00Yb?s(ejRbc^5z#?a614 zK6|tk`~gC_XATYwZ2j$v8^?cLx2pDom7`w|=plSvdoTl0N1pt$&V1NCg(dXTH}j1J z64E6$?(DlSS5$n4?{q6X3CIAgeAo(izQ5pB^X2S{v(@;{`eZCtx8Tc%-+%t&S1UH0 z{pYivKL7FJZnT*|)nkq31>S>bMyznBn)pm4d;~8kZ)^CXd(N%Dn744w{@Ht0Dw+V^ zPM&anc6spYJz!S~hr$CVr=`qvd$!l+*OIIi8+8AHW;`luVJ*VKB8Q6>_~WPpwg)t; z5Izf0t+0a6RnGu@h2Spq@o^qO(G$oVE9Rpdg7V3TjUEo0q|F89HXz-FN;E@P0kNPa zMagvuV>NmmcC{m2xP4hnVQw8~dfU4|%}eSHt+HK$Z&Y1{r`#9RyQFe|r z!M@5CdT%zNwWG&oNj~uKWse624Raaa?CreHG|OL23cRHGrH4844YZG&CljNfnsGi* z6)J;}LX~M#u5UDmgd`mYDNt!)vr^gC7k2}4+t+qTZXlpPWjc0UXOpmUuJI;?em?)Q z8;KU~?O}$jUAt&4m6BPQ8OC(FXmQ`7tC!IaMs1UeAFE`w-1-?=PyKilsY;r0JmVS| zW#>$v25D^zx#P_iVTPwvEsDd}*L8dsY<0_Xm%9FMdD_;0hv_&XV5AoU5UD6B?gFrw z(3+*Py~DuZP7h9JPcHx2!b_TO<2lsN;J;YE?Ty-+pGV8#?_^Sop2P>tTZ5Wlzm~iS z59DN5_=;M1(@oUe8R9jwbWXP=ltFZa3$%jvXa*ms6p}abBZ4SOg2nyzK5-lv1_mp* zltOK5N2DjvZ^APEh**#mmzb@37T9HTF3u^ua68?EDr!+pumB!sPFajgNjfpk?5lHv zOCvz8#Gf^6{DuWi?h=8$Unj-y=3w53{dOzt;v{wSzvk8%Jfrp7o2v!`@CmatO{Lx> z*V}=vIf6$9+Y^8>g&L_tG~V(wD;slYu9kq&vog~IxnMBzv3ogY_%3wx?_L1;Vhym_ zcsZxTiYL5vPEV%jHM9L^MSbr%nNnuTe?dAL*um#?4yLj!&RKnvA-k?)BCMTj3~)L9 z%+Z0Peutm6Wc%NaVvMWq)3u$Q;n{T~i7fgq?M0I?bL4i_0sx@Qzw=YVX>Ql;nC#Ji z@^kp(OCQ>qj6OmVcX~WCtlC| z3cSVb!FLg=+dhV`NnuQ=RMNx@k$R;&=YmSq_if>898ZfLQN4yL_0pjolqq;qY@+MV z==aejpbV6w{=)>f_IrLJFJk6JEBTcW=)mj?(p6~uE4ByFfO)PTcY1PSgXu4j2QwCL zK(|FHJJH?(dkjXn*|kk$L(knWoc_5Zx5WS+1gdEhP&Is`=UjP_t=c17;wseqc*u^x zU}w*GI3wd8YR*BEPEN12txu$Y)w&C3+j$y|= z*ZmGR3}(Ra5McYGHHUXKC1Is3xQH@9MP|++sF1uJ!+`M~3LgvJ3$5%G09RUJr>h_g zI0i_I&Rht3#C#R^zfDU`fAQSt_x$6@;bU)p$q1enwf>_Tit){MwD_nt9ReD!wP&m) zO#0cNRuuw)_&K6YgLQ!AilaRDELH*|7|P8R%9j0S7YV{^5k9WzFTk8AxEP}U{zBWE zCTa$we8m@?zev>DUUx0{DuhwWucFrlWjAGxp} ztrlCf+UUQ^zXHK0a+-=}EP@s>+@`Pm4@#K(&6#Z%P;52p>^6<{4|hD=aTz64Mo*R4 z;8O;`nhv33cFIm8jB5#K=FZmtzy1aN|J}g^LAVOw#we{+Td9VX+VJ0)sj*l?pHlRG zE`-cCo3(Ym`__8Je3W}pTnv2(`4d4ae+1dR0u%U3JbUX6#_~9y>JV)VM*w{61jEf# z0w_L!h7>1LcB%u3h?CW$pLZAjH0LIYMBvaN01%(v`1Yn@;ZF|$dSMlP6__5NbgrC5;`1kw$YZt#eyY<}evr0sOli+Ce4HT^_JyoX7QKoZ{mr=y8 z4cWFVXD}e{PRK8G4v$^?*vX#f8jxj{=32B=jkn(7$2)J^SIkkX{37A?A}#9cX|sO( z(Q#YK^qsmB|5N)(?ZV|h=Wp6r^vB@Jy@7S_d*gbehk8>UrSv_Xq!~!+-c8?f*0eL2 zyX2AQy}avlBIiU-kDQ7jwIi#PR1j1VG47<4%q+N;v7qjXTj8trLte?BC443qLAWsb zE&uw)W#|r*IY5<|c;9II+xGikMQ*eMg^s=tv&uh&zDOcTKfAIK+px^BXPh<)N1lP0qxfGl$*NkM5sm35(Xv9L8DIy3N1gEXB2CZsAEU!sc6 zC?hL_TG;U6iExu!$KTgpY^-bqg@GY^N=R7Szy+k6T5sTd_T3kAmg=6o^YlCF-sa7k zjA^qioBg>5_6qe)#GUCJZf`nEb;fLPMb6l`vC0042BbZe&&>?z(scFqIWpw@+$KK1 zNP|N!NG`MI@!M)N)0*`(LKLo-iGN;uLDYb)1QY6f+D1;Pd|@M?-0a!G-)4q&;R z`1Wgzem6{xT=rX;uJ4>_x%7{hBZWe9?vTCaY0>ENM$h2)!vePOMGS3NmCmG%#%M6( zy?jSL&RewhS`NRAT-A`o7Efc+g*3TLgq7_)*?2qVk))gL>~1Bm%aIqlp)!>r+@&VK(vaF1>YN zOZYKE&aaCCkq_jAudZ+0F~k`BD&>@^sDtIWp4scRsR2vf7&K7rIggz zT8BuQ@fl>hMWr%>Mx_YTsz#C`yE_$0iXy4Wl2mF6kt|tmwuHu3A=|ZPckTCbm-BnQ z&pCI|%=hzu{JoF&d7pFd*spawhNyt?#1TY};L!7hg(Z4NfC% zqxRarqB#9Z^QzHH*2SZ8m9sb_l%z$%Ei8`WBN`D1TcVDDFFD&GwO!!q@CxecW z&a6nE5o<=lcK_1B2Ps+FBQ3@Bmj04}nBgKfgE+%uZo5C*>=~qT=a)|e$>?#1Eb2CU z47EF*G4lOFVL#(|z$27>J{YCll-1!r68Vx%;X(K|ggPL3a#rkoKh1^p8CV?t*fHKA z4zgmW^f+(tMe0wsXarZpT-xlMkg@NeD$X>|k8JAOU#_$CR`8rhN1Pv`W%$1?>!U9R z7k#KqcK=RishLr6+sW?zdh;E%5lM(j5KiHTRYca+-|Ui&z8qvZcy72_Ub(z}^T}C{ zY|QKD5Y^HfR-1pH0Z(^cCcJ6eBYbnyv(D$YUs{#_jvB-lp3ZqlG`46r<@jaE96S@? zbN)qzEiAv8^HoM{^<}b`p<%3Dy(s$OYQ3Gt?xDd$Yvfxu8*5iCTHxY0i)bdp?xHZ4 z^^p&4mYtN@&c7e>&U7x`4F2um{9BsDXR$U5>*vHy`)u{H9})~}Ke+Ex5Olm-OL<9nv*vzd-!sVgflZ;&k zJ7N8c&V@GJxk)bOpXY}+5tUFpVRk@nl=7JUj5k&`pT)5g2t~at2gMR z1}%W`AgyBkTM}o(p-6n4U7N&S(jE zM81|4av{;uHf$C1U%e!l|9;o}3g=|-i&imNe)X=5#)@n792uzit>9*Rl?5bX@|Kxt zEGC!vy;etkQJGuDc-vgF&4~j+owws#E7lSQ6{jV}=N*M>M)eP3yLoidInK5`e>eB> zuIARfkemhijhQXR*cbJYFEs8?zI_y!1k3ALjMU-{*|SEc-_6flS^K4YZS>_@EGnkM zg%R2nW6&8!9Wmyc>LLQY`m#o9kVa}*fs^;V?d1wI=Dh6v^=B@hcfM>D8N1Z}%9+bz z;a37E<7?qF%qKX$ViCBE?jx=72XlO5bdxA6e!HdCJSj=NnR#wYg(R;?l6HwrV^;g%Wa3qLUQW?sBG zm+l^B9mARO+Kh-CY5TgYvp_e}!=tU)()LS0TC$y9z{Q*KioT@@&uSHiI&wm`WO@%6 zIAP&2U<284zqj)qT8E{u?Wk}TtkrnMLa-5~Put{pN@f&G_7%0;qsO=NW-M}}job)| z7;M{76ye(wpXu!ms%9vP$^y0AHY^iq)0nmOQJV>E>;rn%mrP!>)BTyTXCIU0{BX6+ z2F2#q_hqfbja7ZHkDQl17G~GhUotmlr0s)}IYIDjj)mQq{^4|kLp1jbFlfV^C~Y;L z`XpJLoRHm_?wxS&owRqK12BkV^~{ZV0RF|$kWy~p=P*fwPWP#q##U!K@@ktqYM9hf zeXBDM=NO9*V(*?cdXBN_c{g#_6vUdYlYU2yjH36hKi(9nGBZ5~4D4fg<#S05axiD= zk7u=m=O(%(4Nzc>SKHiDV^3qwAoPV>v#0-u9FuYbZj|H|^Gz0;?k!iboqVc(ZsHP! zqtO50>}zUCk%^o3=-CW*jgjvO+2Rjf%1iV(f$Gi^9R=|Fy%N||UZP!jah4=)7-yDw z?6#Ia4`xBvSSB@f^;cynUf`%Yg9VROByu`r0gdTTv> zyKSsxfn}2ZAB)7n(-vDIW~>67iyFA0C@w9IEPBFd{J-lPFEd~NmbgK?L1wO=uKRHR zCI!;k5Xey^OsClyxbXA?%jnnE9saAOgZH?9R}aS1hG;Z;$OUn@Ie1X;)I)0=-9t&o z2YEkaYzdUvve@7JE-n(^uDlFfB^GuMACWL9g$q9}M6CJ77#RBen97`KM#PICjTb=> zTKuZ4KBb+1S+G;^QmXW>Xc2r4K@*|17azM?Z@zr%$!;+-BV(`*^FLHB3SOf9Ys-!c ztLFqSdB5}g5!0{q127h$fN(7&QpFO&6rzC}Ba}ASdA<4MAX(QnSKW8$R#%LEta`Ks z68WG8@N(b0Wrsv?YRhJc1w_SH`hRQ|^{CO;DYFGyp4GYz*im^QDo7q;jF~W*>#H*7 z;%=4gPnSJ9eCsM|2!y9r$K^(}fhJ+_%Umm$``d(-zu_FBfNN|lFkrT>+PaGHTOwm^ zzFLIcEk}6N#wy?%K1C5YqToVT$T`451oIFKgkOg|GF@aEk^Zo8juMqzq16#!>IqW;eX{ua)VB3#LjbDAqJJ9KH0Cf}Au3@c<#m;oU) zqEL%C+nt-5#~)r_e)7ondb~NG7;Zqo$1`K`;L{Jgij<{SEnKxwWeFz zLGHU}oI3iHNjBS!w@B25Bb>RnJ-rt*^;Qnm*zsz$*+Z7JK-n2HrST$q-$901%8gi{ zR_1tj40UVPic|?hRIMJ!-;uSkdP95!<1DjGa+B8>ThV!+#4a^uGhR`A_K1elx$!BV z^0W+Z?hH`OpxoG0EZu`Qe58DKS_byXGIKnS!qEq(be6z@9APyv&Zha7E(KF@516T? z+$37wtLy6EQlH;)QfA5dEr+1;7y|zmRE}BeXNfx(j(7|$b~@Wv*fe*Bu62JK8o`F-JXa_YX<`iBPA5g_(|V zV>kP=bk)y74zmv2ilv@#k5I<7#bUytb&4vwG1Zzb{b|`E3SqZ zC{dDQDDm^988&Ab2@ycnL1Te02yRwcQ@X<0iEbvv@IDeR5Y#{hiK=+vkGaT<3cp-4-ID^VufRHnZZBtfaQrSb(B)ni`Wf@?E+CFTrWJ!+R(w42v&TCa-W=FD4(f`d^oU2ZsMLjFD5X9DFcm zcwy282nrw<5LLg0z*2NUQ|?5;1)+NU-z`FrBgt|#Q@iS9#%t)&hB%r`NmLIOz5&18n1AfJxe}sv+>3^-^@A% z)#_6l^NDIEgn(AOxUhLRelOqlpSH%eGO`d6m;HgfN21#Ehe#oaD{Jp~uwjnBjd>lv z+FUos&xWY#w>>l@3W|`DZ4_4Hhjoc~uQ2ipt$zlZNDmMNQBc^#tMFR?B8?Q|_d8H{ z!)3j)yu_~Ji`B{Z@n)$)>$_=7>yJpi{TZL!h+BT(E#ZTq=it{#_Deb)n#OY zWL9)KNOlKx=~2hP1o2r=Aqi0kbE2Ry*2DQXZab*eS|z^vLl}el)p?(wEY)fYSVD#? z;)L(q$my&1r@50WPNM)heEHzBg-@Xn0SjTQVg(#Ugv^QeQ20w9!xe`2i68|LtssIF zC|aSigyd43RqxOD=g&40yI>_6sP24jQ;tGg5PG;UGgiRc=qU3Ocr<5;%IsCM1>q1B zwJ5L0kAiBU%0iJq1%xb6tdVf4t;``(0pW^6->92K4j%j=LJ54&_-7K?um1z~)|#0| z-DW@_P~efHSlbX)X@Tist-Mk83Q7#!nq6(;>S|`jJoV}2#<+^A88=Y`BA)>dZ=jmYY zUx}VHMOID{Z_%tv9WSnQ1)A=3+4aCe%5jmER8(m9t*!BEbk0MtI@R zYk#oV`F>CS&uhsFc5bylsup$g75dKd119)}bkt30$b_^p;Ww)-fbe206?Jo~{hF%f zJ6*Pa)r?PhU~!=8>2vr2Qu&St8lm0S*66GjG|>-cMH54ln_~6iB46S+Pn1~ITLqTy zSM`)zG;rgQd`ha(?ep(`-L_{@)GD2AE?2vkRIPhpfd~>V9aVbO^w>7IxY1Jilk*+7Dwvg@9z@9I74oQacEinA`l+ zJ$ir=oXPc%IHkz#j#Y$QhsGsW;~75PJ?s#h*RG%bHlrse+G>WxYz&vSIuHw0I{bcD z#(*;za@4;jPLWgSZ%tu3GqAjS{FJzMEVtaYNxLaO19`|<$S(69`*^+9_SP#sZcB18 zg_DdwQ`>NZq&G8(D@PoH=1+2^97T3>oKE#*PN^SYG7)&ZAX z$5YlM=8inK&t?74z@?45ZbPXoMABLCGh9ePF7E!I4c=oBYZiLy%S)$XRYdSwgLCsyxNJtxA^h1HLEdsY8-pUw#91w9l8LoAd$yT`WqpzD8L!8jwvU zyHD6`%JA;eNl;bSZ*RxOWKPjB2fK6L*bndn|Gss@^Kq<{cD{)6#rd@7VeevmrT+9-) z7r^e2IYMlxlLus)r;>69bLbv6f}{zBn5|Spf|t6KlA?EC?wT|_mB#62uM+)k<|8@3hb1sK%uGU`beFdqGHQctLe&!C9_`n+>Z)m-%W< zRZ61m`O!~Zr@&ajF?C9=-hQUuc)k_vjvLZy2dYA)Av5qn-!HGbXk$AY0-SOxlCQSB z&5=3i&Kh7}C4Px$9h1|S&!+oY8=B+~kklTwX6%*%j2_j%d(6StLwV`VCHDj!qUrwrLn^92A3OBUumlzHgy)r|;-dMc1&OCc8`C9FsZ~8JLa|h8b?|yw z?S{CiqjHLrDkbA{a*zN+C|>Zp>K4g3yAM8fJhsjHK-E6Hxs%Lgf@EO#o&}J);?T1Pfpd|`fBP27*R0feZshXr>VgARD^+y}C?^1D;y=BB5d4fT+aUGx z*X8K8fal#eq~%i{tW~ult7A4f{iWe$iOo3!tnR>gNrN#EG0}RT@H{nu4u%d{5lbZe zUGwi5yv=8iV-EyBw1vz(_pjgrT!IhDz^g!MQ$k5uq*_(8D-~o@(Sb;O!A1Vg$U<@x zz`oW71s|=txn3u9n{i6_j-~R#q{)a@IKiO8yPhv%x9&|zUG30w?fD~(l-uR+taM=G zTR|R^gs%iP3^hD28vGjn$*$Yy*O=&rK9Vn~4knJ?A;PF6+aYNW$_|h;h>?l1q^}>? zZ@HnY^HRYl)w7)~)vr{~POgAFd?JOss!&Vf;vUk`f&3Kd99}FU9?qk<9Z_@m@+&YY z9zQR-g;~im; zO+Fqt!%eZoI;p?L`2#!^jlqfPkujBSnQB~wRZhE1?mT89a>=b4VQiwcOPcm*G3Zb-Awi7fBFtA3_y zT~uN%w#0{a?~#JbNI!RoSmV-LWXFCmP)uXb3Zc83339VOy$@f!XgViKTqnHpsb513 zwZvaCck;IByeI%-N+_-;t9waJuB~~B**n1|jjA``qh&s>ii4-ewKF9@k9ONSHJYtKdZ#bLsYDLrL?5S|Ow(5~8T}AhHCys)J z-@17gT9naMs%h|iX< z=%sd!Y}ufg&8fgH4)8G6>tZKf;ZBdKq16qKWGz$2dy}vS13V{caX~FT4ev6t()VHA zl!!QO^Qi{^+b0!am(f}O%A+Ppq{a|aPsCin=w=3IsWDJ++KCf%WzWC?| zL(h-x&x_NdpKI-HYVdr1zgQe9i@YG}R8UR$rGW(6q$KdmM_lzQ>W>e3QKZK9ZwYxd zzP}-%BKN4*6z_;)4tI0BU)w}ZR@z)J6yhOoty*kCLsHW#c}3rjs(TdTDP2cj$s9zM ziR0el0JDSIjoF9q1v?%;rE%oma?8Qy^W))N2eCqVw5i2FtfNK${{6Ryj*Dp+WjHf} zksXj*u6?)uG(F3qFDx#A&R%4pgt9V`!|F#@k+SxV)RI^WLl`#mfS+Hv{@(Yo=II)K zBf+BKXGe`!e}6=TuK1{PGT~VSZkw&52s%vb}Qo7W*|W z+YRk!^S7WerY+?ur=$w3(Oa!iYvaLt3~(3lvjQFIG3|>A#+B`2o^o44R>v0a>LxMF z@MfBVLtipk^&Rac1x6YY0D|$Qb64lC)X(!ClWtq@QB?4U1b+|z+iEQ+@mEZdBNVWQEeLB#ox z%y{Lx3-}+=F2tzYSxi4Tp*VRQ5x_d+NT2g5*w#o(OS@Zt{P%lL{qF9%b7bxN~cZufZvUv+n)kMJ|AbB`n>0D)}-%yl2;!x}Ononhk*=JzrsAo>}%11=!#Hzwgq~Wv__a(v}#CA6P5J%@ll@+5FMkNcK*~rU48PaBM!wi z!3pvNlcIay)eTHa`0F5D>ldZ2K4DxLd|!TxZd!Sr&XK-rKtgB;DIG6`L@-|-6Ktq^ z@%-!oG4f#G%2Oo&L*E1;5lvpF23=Yys9;=mgZ{auPZ80s1D|wH`wX_9_MX~SYv+>} zE^|7Q^L~D&_Xf-JDxcd9}8Rs&j4S#Gu`nG1dRMZxi%Uj`QlU-rU+8!KoxY5g% z%MGEqlDKxVD{Kp{3_}{kZ36m3RH?7W9}E;5&_o*XgOD)dIzo(w|Iva`jAJ_BbxloZ z!QpKSg0}73u{Kpe`XdhT2iHYxj%16x--3DaQaYwY!5O6j7b-X}9DqJw^bys>!o5XC z5e|^pCj0;cf3uu4E!UVzDFue1;KHy)O61W^C1*p6T5EoanHr_$D^6ag^qm<99VlR6 zb@#9$1~QQ*o2g^;d&XvtF;l(j9)lrGach#-CL@VcfyvU|UL6>xjWm2|H4X)_&sBVl zQM`-K4|Ljle^KYGGekeg%AQC9=!EQ3498hWXZd_LYG)A2>Sz_3F;zO6 z*qC|9i|IhA#BJ>ZyN?Q-nauN_b>vc?t44VDThe|57*pN_62ui*RHEiPm~KalUVHrg zDx@iGyre213EQ!6SxWv5>0SGj55ykz50y?gU_MANdmG2dDZ?F*gkq=MuKdofM0O#K zWqe>566v)i(5Kkov>Y~R84`iw)Kxf%INpE&cGE&KD;(t$(bL z!+qm#9YeiY(55Z7w7B(!_JV-UsrW(G2z98-yGJXxt(i8Vbn*b$yEOq$oI;@6FSQ1| z=MlUPd&eZ~3-(Y^ADP0BpJxo$OKix-2HftP6|+#x9bViJ-sJ?=$oByoI~P8NeFvNw z&>?ob>q)F?JI>2QYVRD}^K^O+(}9-MAcr8f0l9d(NW;3Gm-a* zkc-kGM>6!o;0zxA#84lo=4XOHFwSzvx6Dj%!pHnBhHUnsIx|BY-t+H342|^c}6`b zWi6#;2PVXa;chPq#5M_Ex{23llGYvt6QA zK5*3`z>TQD$Ok8Qz2jOF>yqkys7ap4IkXN5 zZ4oCJxyEFE-{+4Kh~?->)dTgraPN5)`Yi3aIg9~u@>**NNbf*L8y)R~w6+mQnwiPI z)|b@m+Sgp%IMrWlLmi(}YcLU6R?&E-=j~o8k*EpelYMpP=BpF@hyh72AoZ*67a}|r zyGFTfy>A)`+pg>Y+bD(-h=u>8eVscynUT-&&c*H?sCXaUT=2H?%zo1TVOIfK29hPhPF)?D>KFGRrADDNOL;BSyH9K=e*!V!r)5?Bd+wTRrttrBHWVfZF&)cfWfWe73irDvVIhcH~?Ns51XfDO~KxIM~^^0ZBDBYK$)b7A* zqxC#xHg-+M@KS4|bNYv-T+;ztYk)z0V?_O8-8hzCp}zqKJm#khR9$Ir`o1I(GDS8{ z>e4&kCqM$MQily#Tl;Ghgb8Hw0HMi1D#e7j)AFu(a=~5QH3=b&eUDW`><(K73GhuI z>7Z*v7UP^tXJFU(_$(uYx0PhTmey(-pKsUM?Br8ewV2B7T1S8-dkz4h35CC2Fsm*BEV* z{)m9saN_1LCI%UpzNvh#1ch}7fOXs3jF=fc^<5j1w`s4>KeRJ@YSJW8fBZp^WMiiz zjnTA$+uwB%@FX{_pBHfKaCx*llR7eRcA~KAC55MIDt{aHwtceSpsV9nJBNuSI~{H7 zZI8$vdKu$PIBwR8xy4TtA{5yv76Ce*tucCo(N3O~RRwg+%Lft!E6)q~vC8OJTQnWB zW%`yG1>1T|r6h4asK46^nKc!9$4xAo#@;Bhw;M-5=e{bA`2ab%!CH3J(jQ{*OpWb$ zl}Bv3ZFoA~X>S+X!qszI>Mhh?v)ivea9iu#x0wu{z4LQfaCwt! zo-WqS_^qveafBWgLftDs>anIx*&5eIXFp7`i9o4EWtv^nEjodrYXzxBftu<%*&~<3 zM(y>7jC1oOC|E|Hdd_o{<1wRiz-{VJY$PiZQh;}lQaC>}Yb#$o$87x4(YDFhQqjv) z5>SC)SzBcUv7*xm0O3=GfpK?iWTF3DhVzG4N*j7&BO%?gOIhKhTXRu~_Un;M^*#b) zC$KFoV9?p6Gr8-Pm|BwF=z|E_&;toZc9{=-;))4{c_+zx?B|%H7Mj3qcQlRR+2zZQfo~MV7R)B4|mN0*;J#(Y;Nt~957C@^Z2wIu;y?i zXnrP8(zkT|9bwD}^I+m|=(qiJJ_!d60Xl_n$B!TWYB{~Bz0um~nBo741v5PpB_G@f zf5Gz_kdV-e9{yKwgGZ4678(E;599}|Z%NhIfbhx!o!&$8<1d0e_Z#c)DUa0Nbgu2a z|I3LNQ&V}Z*ZW4^_Qv`tlvWxo_f(DzkRq$R+rODWD$gIGNI~XQq6EX`MRR3-1#)c! zXje}np-006X|iV~5%6(w?oq_})K;Xp~}@4hJWvjHr~LlFSfEkNvcStOG8 zmLGjUu05U^T_mwEY4rU&MARVwnc4-ITZpky641XzmbJ++hW1Hig%<(>7(ATialwLS z804LvlO^51??nLQ2;L%sU`3*M35E&*0!Dxg31}pW3BCxj?(&!KJ)itMW=`bCMFIoT z<02*(reH-)etKX?6uc!W(>+K-ru-!147XG@(az`7xI@xa0>es({?&VVTHauYbDn;J zSqg!Fgn&ST7jI4GS|8`T8gakb%LkBHv=`+kc14MbXMS&++?#Ecry`Mq{`mI$U5uq>H8q*SC#emuK|zhdz85uz}HFGc*Ko{Cj2OfGRPDNIc7lycme2=Aip&U zL507K5(E6Ef96TXA!EMg6Cz(S0)T|f$YG;hjT1wVs>!1{Qn&9_SEBo*Nkoos&tLeU zhjh%4+ZpmcABQZ@koFm}K!ep4`_G)Z0&HOc?g3(M;RXchQ2|OKA9H%LZJgk!%j$QX zK+tjkJWqgk1p(&G9;rQ2uVD;d5y{A$wnm6cfO0L1I;D8Kc`M0lup-_?32J-JaRF@w zjke3$;a?SLET)0Z)=Z}{9eKxK5d3Y=tH(O4DV!x+O8gL}2-sYc5)0JrnD1h^_ao(* zSgT|PCP{sB&x6+$GxizdDLs62)KE3hGCI2>hF6Qd@#5tJ`Vgpk@1d3G-|5RIb(`TH zMb-~nOukRlo4RI(g;3fdx4mM=8US+Lg{{ z2iF5ON)t1R;X2kCGnwkszS+>EZBN_Z)2MOKyTev1D)UUaF2<$*0x#&YpFWH6Ef1m% z-FfMh)7===C2zy+KL_A1s9$btEwH7w9_woM%$r3W>zfxrnY@Q7Kya6s~T?6Ze3crWn60aEM)0)QCUZt-CL)@+V5&> zTg}w*Y#(_B*b2J26X_mwN$;czEJ4z%^Qp}H%*Afm*o<^)i~Qi^rzxzGk0AHjw9r3Cek&Ww>D6n zQ)!&jMPXn1*?Yi_V`_%6k}}3(i*qI(m6bPo1_gyQcJU}HF@Q_kj76Y~4kl+=svkOl2P~SKTb&0JgUXwno2$Z$qazUHP2{FxF+`s!5(B0S0ZY zl<~h!%VWk}sgrDP9>cdV+{~w>PyL`P*npYsea$`1k_P?ni>&4JM=fGT@&gQ>iCqnn zY-)e}EJRuoVDBsS`{- zfKLJ-CD=FyM+l@jj+U?wq&vY_kVBrBVseMCkkC~^iTQsd{0|Y;N}wJSOzVJmmE^-} zyjJ~cL8wxKI~1X+!}qU$g1r8Qs={Mae>6fd1tWYH0*F#ZR)he&2>{>k!X$|u|0q}Z z5ZtS-5~RQ%T0upr3O6jLlSkwAG|(tOV}u!B{Mgui7(98O8!BFoPjyDfC+74{sV0HF zxu#y6oI*p+u2}^$ex$DYtwQs0cz35wxgp3WsC~=$_(y2%TLw`;J`AFApaoHI{voD} zNCPww4pw(!?IG30X+H`o;Z&ykq6kYG_2JjflUCWDufZYt?1nQLvQAS~;rq)6O0S(i zwjH1Z0OFk}BnT6~qsX~ny&bn-Ms9LGTef_Y*W0_+<)tO>J_ASu0Ud#I^miTw&@h4& z_l0wH2&h%zd@_V2PY>gHW9W zP)>#5i+yRO@V2=5{H@z@lrx%08Oqp8|@M%XZvMpYBfz&`kLa5nqvTcXpoG z`Ggu+;K@}@@@OAX1xWG|6GflWAPRGn(?Q>DfB{8-E6l6lyfe1pu`Cp(UebFfn7M!7 zwRReISkTwISlxZ1*r4Yw4Ksm33by*bp=tn%tirmT+=tlIm@L}x410ziqgEGu{0eL! zgw;l8izO*8*^+)y9qUMPAHN%s-5%nd<3(X@Tuj^IF&q&+@;=13S^_e|zCOx_F2?bT z)5;HO$Ac$bYu)S{pi5^ifOtoV@idPMm>a-Z-hy#Ut`Ph#NbdwjZtX8J%^vaK-+yrW zbi{7zMx2Bsz3=g}7$4ho5&}6K0ymHa?d*i#NQWKfA%J`yD^ldVfY~T6jJb+uCnnO} zyDPjUa*OUw=3`UNW>}^14s;a)gBE5bq|?|2#_B#J%hf3pk#5{T_*GK@lU0xPW@X>4 zRks=Kw&VSfWH26j9uQeWof{y~;yIrAY=ND}UVyr=DZ#NY$`pO7!>D})&EpK8xX9&9 zYQ@|}OkZ*6_y+38a@rJ~=a-vI_yBF;@#?yzcb&)bjVX*?rI;F0$QDA#M9qozcU5?W zUVK0)#2Es{Khq{Onz=E)SwVK=`($Xn3C*Kjw5EHna}CBVsc*y0yuoV4Jy9s_cSPz4>UK5JGZ=cz{UQZ$*3!sos^gRkO=qaI%E@Di%`39id zX0n^GCI<8P2FlbmJFcSduabb99E1q(5aU%|HF&koW>J=EAna*>>=0s;k`-EKqjALT z?`sh;IsMA^Z>uB}y-Hu1={v%%rk^y<*S^=rTJ%qQP9}G`g0mBqIlk1%qrova(fdo; zMFD_JG}dF>G}WR%$j-4FfG~_Cx5R1UxTlZ)1cmzU5zJ^t2vR>f54U-#j`CvtTY(ac*A4LYlNqT1X8_<6{2VR= z!zL)UV>{Iy7Cq&qIQoX^n-jU5!AhhL%G1Xia_*MJc-AEG!eb6U+mw8#MBylc z!ajYX4-DtmJ@rQ_bP)u%C5`nU*ZIavrO3k7SnFJQo2eotH0l1!U2ehK|s&&vPZ=PCe&(Kx}>>t4WK~~$3W9G{}pL`2A;R-57 zlHsud5Y#y)*v%gg;kchJgb3oR0*LS7F(ce%Pw<=OdqZqutJ_WzyxC^V$ z;o<2|OXBCNNR%(nU-%{S`r)`bWzDPC54-7njxs$TAJ)`!6g3aKU3JXYJaliP-}S@y zV54c>`S`l17rKYs@&}h>L1x*0+oc zvX^w0B~ks7JiX`^4eEWCSIQY{X?+wC8KD>%VRzQn_l&LY+cRy!i`^poho!u-3l-Fp zi_1zB)RnT@kA}3b^pcbO-0uEvP#ccSiaTYLwlYiRbIv=>qi(mFcAqy!d)tq~vB63cb{5<@4#1wuFQ8f7M6^-jJUdmvWJcO ztCMY9Pg%-mS;{x8X@KX;T6|uq-xP@CwfB5dd9s&laMQDMK%*nfzxr*%o1Ue3?KNPB z@a`yLN3e_l%jn7LdTdsiZx_5|;J%@7CD~j#;Zvo>1c>$O0nwa_PzM>sbtV4 zMK`M7R4MBN(L4ox&~KUyL|WpNt@AlYCCl;{vsW(5va6103obd~4)^gC9ZC}anBaC? zQ@mVLik}4>39*zcR!C9^ZZatzd~}3ao$S?9cNwS`bV}wkTCZ%l;rLFoRMYg7=apZS zw$EKnZF+pzqJNcUVOh*1C?!Vyql-_#oyzQ z?Hw7k5;Izsf5RU5F0M}7S+A zL9gtwyJp=T@Qdw%OG!DMmz=z=Z-h` z(SghYRv`PRyuev8Y4l8Eai5-C);XX&G3rbWCbJB>7&Q%ctiP0!xOMj49jJL2QA?LL z@(Z2qMa@!j;;7pV4cNKEPGH#nCQ0vBI_8u!DMJlmVD{9ITHh9nNbmS0EYohJlQQn% z#QkKq`}5e-gP%5$Z0=}_J+1H>1v4lBt5X~a zRGdr&Oh|gqfVxi;n6q|64iv7$g!|sKr$DB`Z0v11=e4fglo_VQXXpNM2g=kYMGv-2 zbEOd)kYP;UPFZ*bJ89wDqQv{7f|p0{39rcgqC0TOI0?dsUE`2CI2(JFzAP%^L!fR{ zT{iRWJ=>}15RZ{gtj*pP=NH9XZemD(L7%1XNQKEAznynFc8;v^2-Vvey~Yf`<-R2E zB1vu#^^KBm$A@y&3h(%IYEPfxSNV3cI;)MGoht_a>sN}pioxnM_w;kcOLn}C&Yxl}XUlFE7s zN2+HZx(8d1NZw9p(^xT_id^0YyRp^OF-ec{bgKHK>>#JUf|p{)v%s>PsKfJtO52rW zV^~!co+Ekp7@iCVr=Fv@*f!%OR(OmIS~icd%GuE_ZLO?AN#FV~Eh=xmKw^xRC}NRH z3~q0Of%m9<)VJZWKYF(n8+5Hkr-pF|18Fkbi5s58YNfU^Jq7{{2C_%qyG>2lv467T zsZ(oeeZK_NFDrWMKx@~4VJ_pl_lG6GdeCD&Xp{Ph-s{WiPU6kQE-6mNVOK0^SQruq zxdg|-qpCFQNh29ts9^-kMud|FdgU5EZAyD~?v!QMZ#r`=is?IT-${6^RQDV0cc0XV z`Dh~P`A#7|px>EX>GW40idc~4vQa0x??u(2xG*5=<1o0O_d}fB5uJ(iD+KG?>dSd$ zdupGL4>;n6Zt3YM3p6S~Wa<>3cMTR^Jc3XJ>K#r}xIzFb?JqBr%pPl5dCiB_Jfk<=d!JE-6(d+mAg#46+CDE8cA+jfgX=G<;0{MP5)TfgM2J*B(t3Sr{GL zkHw`-_TlvKSXm)W5^ps9oUQLrsl5RVVee`mh7tVKvO$6FTgz?P&3_nNS0J*GatbcL z|9jMY zej9jw@!NTE8^z<0&4Lsv-;_h50pEM=F#fT4d*Sv&OHgNATaeZJ;@N`7=Ws$0Y;i+I zC&0^f0ayDK)`v~!$Y{jnm}HE5(K8C`q-0WVM^i1W2N^@Y zLr?flgFvL?u7rqPN!r1r@qzjTupfkcnzfo3Knsz-h=h!3qtL_`p6?z3qip8th_JUrie5eg8Wa^{mnn*0T97SXE<@6|?!FGxrk zpO5QhzDdFFkSv$FM+F{b$ zx!~)E3rMecqujxN7Pt?OSad$GO##!EbyRD9w|^zg4#&ax;opLH?LUs(ggbzUw_uPF zyf|I_f_+AM8_0#xB)9}Ii^b%a;?!;$+m5H?6JP8`8G2PgElKy~fiqaDl|AJ{?_*;_ zl#Vc3`^(%9x^_MvVz6}HIWMdV=QB71aUDY0lU*RZ7~!^^0*;){nBdWqk_@>;qK>|( zfaAviOi*B<`-Mq>4c}PB`|5npZ#WwWyKXUQO70YJ#RN ze>pd2?2nCnTMbz9W3r9#2?dl##Q4ftMV1O~u8`H&!}M|~h(c;pKuGgsQIZE!hIag& z1az{nZ#@QzDSfNyyf#^QsOHJ)+HCftqRBo=GH%0<_jeO<$EK>*B!$T;eo)ab@Agv>f4HPgyKiF;WsSGGJV; zq=re-eIwH8<8ErCsOI}G%SI03re+u7Sm@tr>IO8=9i2P&NxA)|FTE{)U3#`4Q75CfrC09!-aFzJhg5#{$N9!g<$o0;(ytOq5~5<*|mX@{aDtvdvYO-BO7r%G67wMvXRi|Fv}|o`-Xn{|-M? z&`t2a$UjDqGj6M}rI$M(@7>#-;g#zg^O;YgwR)n)mZcWR;xWsd}tU zG9|x1bU$|Pe8>w-7RHGJUFGacB;YPTR`h{?Zx>%oRBOjhD6e&yGtKWou6aC+zhi}4W zGETJ0t7XUeyDf1y29OtF+ETaFA!i_$afQfA^ve=xL%Ml4UR@ZuJYpCkt`8ho8HYE} zDN~1nXEOLGyX%I6mo``B>sq;2ljO$f9!@ncirUji_IeTIJLPAE#n)oy&E`C+M-Y+f zb;itDv%eAhcHy!W8#n*FU0yAO874oSA)!PP&yPRqkfOA z%nw@{ojR0I;HHp$q99CD?KS0TAf!TyybpIy3lNTyy#?CP;3c4yIt*&CbC;Q1}04SVR0xgIC zYTL&DhIa?k_fHu*t0-xhQ?KP=gucs1pgD9Qf2RK&afu~MmDg(@%9|%)y8lf6#l=e_ zU$pqmQ4-xHjN4-yw8wKncr;|6M~M#?PRmD60NWTn0we((L+1ai*YdL`;_H9^Zl{m5x>fdx z;Ri)QOQF%dT;22Xu8Pe)%a!$KJ+i+)_N}SsH%j`K!lLtbO5BQ`^{8ue&n9!v1%f7| zG$g1h;kQ&wZK2hf>Wg9Gx5RHPRaP^%x}OT4R?mDiogO5K_|k}Eh(F%^=K^rZS4=U- zP=cQw@NLj{>c3|{8GZm=FYV`Mz&oU%=p7)V-+sL)C_1)MV~OYGx$75teq&g%xqG>o z{;XL06=UDdUMi+va4EWVOU2NAU@$W)*adZ zMhYna`M?j;*FwGq&gYMz?^J%;^ZS#J=J=q3A@%>GeCPSGGVZd%Ph(GFjpyGKo(Loa zelPw=JR^jJ8NbeY_|1;_H~5bQJkho-NJb5f1~edLqf=XV@+&@;N$LeSYWf4reCQtM z9`~Ql1W6xRC!dZ>W6kai2YO3R66gC0C*D$NWhlhB23oDMm0nT!j3s~7a#)3DKxC%J zYcW13(`>PCwQ)Iw(lK9wuh|wobC*tn@oc{T{)^2>&)@bXFn z`rOcs=u5!4dJnr=zFy`i>CaViyicITAlR50)#vVy$tmm4-G#H9HsU=~t24j;fyCrY z2^c$ibCvi@2-1YJ{O2#xG_Tuy2pYG5`4OE^+mzUaK5Oxt4|jrV-tJA_a{2)wFi@Pw z5Sl09ZsOIbc-o4u>MC_*c&8ro>GHjV5iSq( z^oMBLu(kJqJ=LGi`fS%4!Ru0glOB!V0;~KIgV%-qhrynz;QdJBY54|AauP#EN))+z zblxR;iM1li!q`~9S`cRdTUG_%9^Z`q}~p}coi?4av%p$o8{yrg}K<9 z8$^4jIT-BNC?CTri0NuDm|WD%JV%{K8mh+mKqY|Nt#J;VjmP=~>gX7la>-QV4f=QEzP z$`f)789~T)$p}*$JQ}16>#Mp?32PFWcBEm+xZf)O-|SiWx;TIkfu)EN^9nL@3v+XS zg%e;f<&}F$#*Y2eu7fa@1*i+tY=-G(1a719jn&yR=fF8T!m~qZAz=0+V-~l{1Tq&l zkXHb%tDtOMv6aBVBooS`gvNVppJW4lzb+yv{>|r^&s#W8;EM>o5~2m4Lh*kngkSiLavcd9fk(B-GrUnpjd z>vgKTC}Gh>arbS3nDz?X?*N1b7EKA{iNJct*&&wi{${t%xG;CN!a~G8fRIYCS>WdB zUT|}j5I)6UX$haLmH>m3V5nENBCYlv-wTGrMQ=+*I>fE{ascRk*=Ap)_XnfqGTntR zpVhd(4gMO=M*;w;7M$G#D%Jq((c-FegljAvJ={)JX7RFUR0)UY0UFD1{6cb8IOiA_X+3)>bY>2m|} zGGR*?>`82xdMQtmn?))2X;EutRxz;ua#)h1qtsTV$)}Xju1OAU{D}9L5Nw8TmJ_5s zXwyXsIuo048vcOw*c}bZifhxw?$V2ksofgcj0mjPY}5#AroGFekN?ojY-LQYp- zycyM^2GPdjFC}KT?exlp6~uHxHD7 zcib$$=|6`Hx|Q0Kf`t+yO!P)bM9L(nDB%{Jr^cDENULwA4%JksSA&Y7_}3I2$7nXy zN-RZ4E!l7f#wi%5RHEl;Q!`S3+o2xUi_CVK?r@7iKDtb#Pp5lx9Q1RBEXh@M;5)35 zLMM>dMZJ%=)*=o2?xnH6Rs1i!!>EtV)rjBqal}{k zrF`!UL8gCeLdTtgp4r-ky6*#I0bj}Y+O;Kgtfs!gVpPvYA^V2XvSCfe>))+ikchI5 zhyTvMe#bF(4-`N9?yor6kA9~%9dJ@t)ub1R#_|}5w*X)sq;#J@#Qm{rb479Dj_>~G z-@YSt@;}bm{2y2U@+EZutPa+dl|Do^iGPC?2E6|QYuLTE(`o|A6f6|{KR$?0yuWeF zKdyg@Z4gJ+VJjOj9NWbqNf^V*DfYs;^#5XzaQToX=y7S+dtKky*c|@j`d_~J?o({SpsQ=_ zZg&P{oWWoYtTkSrCjR^HdmbnLIU*yRZDyFRRglUh+;VT6w9a2LHAmOH6&AH%Y9-fJ z(E`-~K|Zn=I-ixo^pV9|s5jw$(58i*;MS`%Ce^JDj#Z_RYzMvpnC_9e#b@ z>Yp6$esfFL@DF}O*^>YL*=z21e>)hJ_rc{O)%%W~nf+qlh5OIE+Vw=0p^8}er{KIt zQ>)ws73|Hgt>=__eBIopb+h2gDAgNs)A>PiDn|EV%X-9Ro{-5bva7iOIm& zIY%jP9_irw>j;%%-ew%)?6_){6PWTW#LO$5*?t(uT3-!rT{8V^__giz2VC28W1#R= z`Mm?DUMz0^7{Z#*k7Qo+Z&1BwQ-Cl46mD$wLViv~2Gh~NkBbH5Mg^qqABlj??|`Rc zc^-=XJuukn;n@E3j`Dpmd6_SMU9tLWh@D0?P`MAC1_9LQ?NLn@D(xbY`tl=^6#ku_ z(!O0hQ})fO(Vbn%jYn~Gbj-20R)qHZlwyZ1=~=-QJh%N=Y^`^7-5ol8eCrK|$b$Ph zN!PG{!?Dh>E@zmLF-A0lkeKuIYlJhEt#Rr#ar7U2Y2MF zKTy=5nqH;w@91EDLuI(5E@FQNRIq;o1f)~J>Fdcjb)Y{o;JluUO?ReZst-eGb?2h; z)d$i>X16)wkaX&dp58!+SJaISJ#X!KTvJSiX{Y(0kgXp}T&nuGBfa(e&Px!Lh6B^a zh9I=j4}!S;w26=5WC(W5hp=wiLxzID=_5UleYJ^81r?_QA{v|^PF;qgEg_1XK37!< z5v};+4wRNY67iL8ar@6PdDpf#99TLnG~@B}@1Al;ck|RaM2})0KR>f9{(kNbkMS~z z#aCh+3$^Kq^*@pGY3VyfvPRx1X5#_!sR9_->I z=1B~E;-{NkrV}Bmp2^7qsXAXcz$0K~9rdvAeOTD+w%R<8xWyrSEMXzu(xr6w!~q-D z9t*<{Am|7p_EtkbDPH7Vd$jdE}0C_ z;L1iJ15cAylEDzO%l()r2%EqHoA|H`2{A3c$WeOc;+wgPDl~$w(Ndmew6GEdR_TMu z;2AoUsrq}jq-?jO_^6&*2#91NAeV>GaWij=QEm86e;m!8k%(!}>kZ#+_%rffuRzIt zP2E4{zjHonVOP>tC zWyLzgv;Yn4r$Spd^ygsMZ< z*t1GFxocIk`PtT&!mF(h0zuHL>T}4=MEsTQ=BGmR-iEMPe1FI&va*fQVFIyWln|yc zYltxpt)>HtA<}vY5XCFEce59v&0S1{7xV_f7U7QKw8*eJDv<6(1`O}n!G}I!jhF>8 z8X#k8^H31Tv|lr0hgvU8&(39@%fx?{eeT*rGU%3}OOS#{z}giBBt)d%d>S~qJ1%u_ zSC_#guF@XytS4jA@5e>3xdatUwr9`YJ$p&I`QA;R@eYdfpn@jR87Rh>VMV~F#{Zgh zv0`IHLk`o-JJ4{EpXmrNYA_EKs(plHQD3veA8{lk6N6Dxb4i}K(y2gNT{AX1v@H2v z%`!P~2+UGGC*xa~_;)HAi@p{phvZwGzDjEVHq}#bU*%YjQvqW_38~9*s1h0#;BA4uqaB-N25> zu?CYVfo=N2O&N|x)*k#1ij2JfxojKC?)z8iZ|)hN>@ppZ`#E~~ejR_m_s2z;46ARN zTDZRja8hd8yOK4R0u4%0hXdCXB=4I1uQ=0lJHrLAuE!aFlTOS?>0iy!+>lGZU9C?p zO6@6sF=i-}PWYs#;>;ENly+l^jALA6SH#to#!ba4s`ImmpQX=daV-DmY1LRjRZkYN zTi!L+(OxykF}|=^(gH7B(|=wd)$Nb7n3O3dPvJcW?)Xx*Aya28<(NM}1;Jo%IZ?;a z!bE}RwJUQAq}>7{mwT_iJO^9W^K1K__quwIGgj5zBnIrhceB&?i@Nz!trB7djOh9; zP5RU*8t|`tkB|Q(|n7}!(R`@_hRA)h`dXa9( zr=n(-#851mgs8dq#87kUvF}7va34p7DMD?w#A!g;5eQXMeUNlCT=;Alv=+4~N7UNh zWfDjxTZlWnKXe(!!>Q3vbmS&$$6um-Cmrh2nQN|k!A~BiJg8|70M-}y|*f+95_Cd(`S6MBqwJS*+ zhMGKs0%7n3@P{OJrK8hgtXLLRJ}JB551>lnp&^C*yizXlEeh0(8WNQHLj?hI?y4&O zGqk^c6%0r|y1bSOJhyE~{CxO9=|(1H(}|4k2)~Z?n4TO}Ki5>Ek!h%=7*&w^z6gTV zt%3e12$8O7O7P>J#ikTSdI8d82m^?Rp~mT0aQxE!9Q`}&=B@Xp(uO}-aeU^Bb)`XM z`Z^oGG9H)1bktjU-4Q1QOI1IkK?ix=i?zrstfn(t9lgPQnOm+aUu;MnaufK`j%E z-Ihd6*d@wkxrX0@Q`m9Du_@t#>`}xddFw%1R51!xO=Q>!w3S@S8_-> z{7w^cxl}Dq?NJ*6EuSa!yaW!%IZ60>fm_IXK12vdouOG#+uf?*ABtdT=p4<&9$CM^oh*2?i;o>q*GSOd@IiQ z%t6{6Mi>yswWaHhhEe`ri+9J)-sN>i^?qpZ;Lxi5C{rmlIWOgW^Ci_Gm+lXj_6 zs4|DH$rozfaY7Z>dbbj^33KJ?o91d_+)LQcHE}BR$EE5fi4mqKykRFG)D{mQ;@NRV z)7rqkbdLG7%ro`z)2gYRo+-l|gD}oG?wR^fMhr_PZpbSK#~OJ(ne)VXz{#L@eT8gV zf3h73fk_ATM&Wj9d?!CLA3(n>TxjvC8aNaIA`d0dH>-t*Yl9i z-NxVk?Rffs+vooF%R7I+@czdizTX=Bamaz-lvaVIYPn>_+QxIgk9-r5ivB`MSXDh= z??L>nPfT+#gr2F`ZOTB>GOHy$*wed`8X>B466*>))dB4j*MdE*S^3~jpURO7d7Ts2 z#1RKt8oeuHsO&-GrxegbSZ}rZ-DJ6UWwf}fBv{>M-8>gmqSiq$9*?r63qAUEjAJ1%|gJs;R9>Am81U-Xx&MDbVA42kS04_*C8+tPA$soxHat zeSxQU#G9U26TlQT8kM-W$JskDs;BO5dWHl0=X+2uioWucJYr4iDyjCSuu*PljvM|t zDl9TtpRFF>Ue!pQ@w727A|{#j*Vej1!;Bro=vR1>tXqT5yA8+WgU*44StAL_Z4VpQ zcrHLM>z&*-u=9LgM#F=~m&Z_0A`0AGmC-(|je1A@U*T!GWNBFv^MFiYD&vTBPt7B7 z#08GXs0XvtDg6S7$D2D8F%YWZfm*LGmx)<}*1LXE;uF4XdcGMT5a$w%)YVvW+dn36+Lg6jF`p2U?fGIF*ZeslDm4)myx zzBo)xN1jI}&JS3K5;hP))v$+NNVilirXvl6O|Nog0!6fI811IkZi z*>O$X(SgDq2jL5t`@P6~M?F=?vAi#}C@il@C*#c9rBgKu-7rLynV+f6M`=cF?cD#3VJeXp`F!_O@wvd4Ki_!j*F@-wVmRF{MDPS<5yhU)JP&X2y zZp-f~@mKd04+gZ`Y&~uHfd!rTM0^|6MNvhKMYYIww8%>2)=$q}=*zn+S`#BHmPf?E zzIY6g>ebBNw7bEAbr7>V>n?^=2} zrecYqPGNc9E9vWdq2@6u_~$Qi%?XuIr987nIU10XiFU3@N6a&>LVaJ!A!ZQa+{s;1%`EsXHOCPF zTvNZ?e1mJ@6VArI!Y<9v@uJCPL?5B$PCgY*P4YA|h#VpiuH|WYmU7}$#K{PlOqi$< zJueh$1=4y{E0&{sFq4P=nH$&O(Exf>@vtY;32DQ$M`I4n8E9|;gTC0hbH|tyze46n_LRzKezIIOLG=viLZA=_ z@AS#-+=!lMr}!&zuL_>H4>HZPZQ|O3V%vmeGj10apj*LLX2jo*t1;Ee#*Lx z?lpVQ-}c531Cgu`-N@C=l#P07rfTF4pm4eU-xsZ~xLlaI}n z^f>RXxHZ;|ScCV8COep$n`>$I+<4!o{cV_FYbhutHUtS8mJgXQp;2_oB0WS+2`5rR zisehSzIB0aBMH@kg{{iBjc22L0uX@(hH~1JgU-fPsb5Jzq+2P^8}1l;!j`Vs)|cSE z-Cd2H6?x@JxFScI^E&m{{CNkIjjEKk{zjNjib=aqcTV)!1$qN(dYBihZ4A|23WaW- zT0kpW@J<=6uS!jMohfbBOo=FLtUJ?zUvaCa&e2nqxL20$58~RU5AQ)gmZMjn$V}brFc;%X*%^^uPr{`3g#fz!(u*)s-#qZ5m{!~ zybov=SrH1a3U{xIDtabZ#_v|;Xu#D7*dX_ngw#` zZ21jThOcKGSgH!y%Rf;bR)#oTX;@pxPP(wd?fy)@TSvZUyZ#!T;eTcR9tyxsfw7WL z6z%^No%lo06#|fyl7NucOcbOR1Qw(^0ZWe1CRL1N#!J?=DaWqKdv;1>je%Kt_@@Ra z&`tC<=6GXC6*A?R6A<7v)KaHYopz!NKTB~^k0qt73e3uapU0+F1v*J&0(=mk&!4z; zK5daVOb;Xe%BOyJcBe~u5aNzVra;$(XPW-eja-Q5yA!4?%SGuq(+FQw!!w=deohh@ zt)yVW(+rCUo#_$RI79Rmyd@|v`8>-YZ>oeaa>uq3`O+7ld}%#XOopsLLL&W2S!fxT zn9i8{JY&H;CYMg-N(`{@kp8jAtV{;&NN>_ezdD~1R(-(zeyF)bG%AAG@!CShLy1u0 zh{T}hm`ax`eJrCo(+!^Gspz?zfu;WE)L7ePab)+V{MjWz=4U@hfsjK z1#{$p8>Wd9TF;C`p3^mv(9o!@ktU3;A}_BQpzRok8JjSzo3bTO@fj_&g6ySP1ufkun6I51)YxS zfC8*0Vu^!o7lGY(*LF-DTfo5p+=sFn(SRHybINT!$7;7B5hvNPEbo?|>t z`2=Z%h^#zK($eJ^rlYe+@_FwhyOsKR;Rw)1Vw;VFn6`yYwqBHl1RNMD4h!Yzr^aTO zM<>Rfo2SkpNvsi0{VV7}-@mBPb>uU6nv}yB1{b_|R0F9b-v%G&o=NV1|8J{A3r%phXXGq zZ9G}B4A_t%hjEI43*p*9K>Iz#7nkRHipJ~+aLH85i7vIFQDlk+s|;z7k$}foueNwv3Qsio5K5v? zsxk?xh)b|?0OqC3k&V-Ek@ zsVLv!??>MLuVbGqI`u!tgByNve;SdHeZ%L6keIa}ynE=_^P3|5GVVkRS6}wrO*ECD zJD(+;^nqjTF45xNn4GgxeY#Y;nrn0;K2gQ2Ha*DWS&jzBmmY78fXqn>bplWW-V|)=kZ)46nY{?^Q`|y^RE1-entBuhAW;VU2(qr%7jmB+9iJKT@*{6 zsM(^t5n?~=QXJy(q`uCtY_prgaBo!pw#zx``{P*$+g*x-?X4NQ0AEFAtV^o=^{O|# ztGD1(V6Q!Wweawbh+VG5o9yYVFuOG@Xyl@ccBB39>$_Yp=U&}Zy=CSuGBICK;d7Ks zf@L$89lznCJzZM>SH^2kpAB%04(&_OZVddVJNz~SVP&x4r3*I09kNjtAAP0ci)H*L z4f%8tSM;KoHx^VMz51%%gGKw^aKy7%yF6JJbp>bJF6XA-h%esc@uZ<{OW9`neqxu> zps0M8CsZbPDUQx=^$Hp}vkh-4QS#n-f+dnxFMVx6y_93U!^hcsMZk>XThpo^B~R zVE-)W8@F@$ho==H#fM|Aw$NiU@!}E*$;J{GI`wHA8CG4Gpz}>pRB~*7~`c8JqCdA#AL|r)+yZFhv<}LMKEc4yv8hxer za&GOGAUfL=6q8#^Wg9-Wru!eoI!jE(BHegOCsXXTET`o^#cPdpRE8@ABl-J)J`TkYjOzf!_r@BEyqVJ*_g0 zhd-GMMEm9kb07Ik2B(H89{GIyVDGt}4`oL(XE{3f9nAc@^S~Rh`|^#WcevB2bItUe&Yq@VAKq{OBxti+*q5$@f|xGAk%KtV#}Qe!u0iR? zq^63})Q31g}sUE$n1xO@AI#BJd9u4==eT=mFx4RGed(C*Hwoh z0#AnE;D!GGT*JP(U*WY&c-eVx(TaqLt9x%VLY(#=7M!mp{~#=aT#-Fpf@m> zXYdHUr@1#v_*7x=w8)5OJW~8+qotc71LN zn#b?u8m7)EEaOk@FI#^3^2)Z$`z=*BvRmDwE=iX~id}x>G-L%HM2$LAqFHSoe?w>t z2SE<<{Y#S58^`#<0d&(XLCd+<10%N1-D+O_^)XMWDT8C^lTIawG=!-^)KCPVeC`v2 zUCiPA+b%mtT0RgLJ<+Gd&^`6U)y0?JScX;`?EZA&i5eimwGZa*d)<-TEtm=ExY{IR zWIa=;^%)CJnWuoA#BKh;Q?F!^n!|_ubmpyrryUlPV^Mltgr2B{c$%Y5$v!D${pUeQ`E! z`p;FDbNzRbclf`E>jvfJTzMPw@c1TFUwehbj+d>Q?VPq~{=rvnr>n>Gqx=+qq*17FJ0c8 zNo$XYqH4~qd^_#=@`Xoh_RN<^gz9q9gnytyWcrk)+mWry(&(mZhHSpgFK*s`IRQk6 zDna`wwYlK7ye&+3JRkv79A>v)RbCRUnkVQ7ZAUdP6?V<3!1xfwZNS8%JAObl??uPQ z{``l{+pi}$yl}bW0!;eOoDDBM7O94=$f@06?-jH>$f_H^4&sEqoW2t!VfJth&E67@ z%sXf#X}&y8`l+GaGk&7c8S8*nmJTJX`_f9mO# zL#_XAqbif#FFiKCIGF4kwn{Y?G#>jvnSW5POmvs@oJq-y9``MPFH7Ldw)tht<0E^k z?;SZMe^{>^=*xX$>KynLDti}=-+7s#zzct9)>NO-w1I~uT zF>5=CG-y_DAfy0ts@A3CPPvbL-hHVy9JM-1^~LK#0zsJim*uFrb`k8GaoDS zz3OXKXc8&Q?%H$idII(S_|ZLY9AF5Mbhhw$M~^`KZ>Pp z#}`F?(ye~>Nt8wn>qtz5ik^oPN*-c^&kIH43EYWGB6HqR%g{}sCXQ&x5)u3g;kZ#+ z!{_M7F}IYM>gDDKJaeOH+3}=0yN@dtAMI^5ZJ%4iBQA-0(kzd;Mulluq?P{;F}UhA z2SZe*08;<8>^Qi{5{ZcF`>RYv&aNYQ9~P`M^(9b>TY_arzgYiu)tNZ7qjbNcUsjzd z^5(_TBE0`nQ@9u(fYUBfNL#aI?PhCIvS2u)A0oKToQ=+Kj6^AaTkl$q?~}Oz*AWT_ z4213-v9*%Y+#c_`^psSj?`%P7CXJLqjVnlgaS>Kpqcgvv*n?M?D<40(bR~T2yj{T~ z7mo*kRz(A6djV)!pmfC}P48I1$0JLlLg(&+)IO(u4%*{{fqMNH>zlXK+N8tpM1H(^ z?k3jmo4II7vX5a0CK98jrmv|E!^Zx=tkzpMYxn*Tz|GSdd64FzBklQdi0BJ&UD9!5>bZqr)E+Jc%d z^J?ao&aDVK{9W_862Y>#?zPAPGXZl*Xv{KvvP*IErF?9BLGXcYcB|P2-KgnOez+SLKuBE0bG>Z$OJ2zHu=2AchJ{088Akf3j}#GMvz_h*Zx& zwOoRBI}`3xbl@Ouk*h7O zO1|)q3Q@17*v23QZChP1S9^b#yh8hES7^}4QkpcuJQOhbEUXA;WH+I3mDNne5X)Tc z$*a*W+LN^fr#7#Ra)czGBRJaXRa>w~`=-r5(p`h>Bmi@&DO*&4>j=B+;NLL}NA&}J zjznH$PD8DHgz09oQ|ZjonNNOio6s@lC{y3K%C=VCPToH`H1zoKrAvo@iJ)j&2^gL+ z+MU{rSp&kZG_ZsUuveIyv&_95qDle2=pmWN1g1xI>Yo9)PBx{q=>HoLTjt+;KBUlu z@{*N{SvlI@$f^XQJKo9|Erj17`vJ|;7=uDnIB=i_CGaMNdBm;Cs1JqUX`wue=yebp zqD8&YL?1`rCNZDm5cQs>sVtFPC!IQ@7OCA-GLEjZZ3rrnp%YXKKwYiwt?ob0Ed4!B zsFuhQ%4Y&*MT7_xiK~yyzeY65q!+}_*|UY-pN^LNy+En!5-7XAjlSUZV&C5yYyZ0C z@P+TQ|L|eP-Tzo|%KpLY+ipF`SmCkV{=gqQj5B_`x@Wi{_m3NDuP*oa&x3#W-oEk6 z2c=7o{BY(^OErO6Rf@cCe|hc7-)99xAB;U58&R6nHnj6n-j#^bWL$`ic#{0Z@XjlF zH|Qf*TuQTBPmpPI`sQ@1v_9(n<2Q~`3E*-uLVDFC;6pps8hGjKb)zX`;{$X8b$ZnM zzPsiM{!kok&4Nb0AdN)PsKoqMIr4>Qm`kWl=S8Ez(!OpxOBuH>r$|`8#dBBX<;il( zM5x}R)}IJ9K9(A8R$SIB;28yhFP3pNJK(j}Zyrt{s_mxkJ4hREn(umA{>$7SHv5YD z?U66;6ud*+x^eK#mtytXG4nh%-zo?%?h@2Szcq>`)}}s-GpR+qt519^%|(XNl&R55 z@Eku`hfXLmJ>+P5UC-0pV5zSM)gR*Hi!9 z1yz@|BS-eIzGt9!?>^O`^EtAyv#Xj5a%61@<13dXoy}dA@ZhS&u*r_;#-juy_1tCtPE9-CuG$zZj zbzJlZnvfzf0lGxeiRm}E2cgarACtW!XQ8;a)kVg}#Hcc8!t0F!8%Y`X)~Mc^fo(X* zEHk}wv%OrRNy7~dukoFg!QFInWm|J17UKk@ww_hJ4p3nfu`yJK0Cex(K$9stReMRH z1U4v;YQyy^$DuBsu_JB73)GuvUx=L9|6^D*9Anj&1rrT^1cU zI@RkHXn;SM_*t%>GD-(}M5^^w#x!Yn4#yB7f#C4Thq~0}=&A`{PKr(zI5iU8yEi`C z8TDxV9+Z&^zQ!wE;V2+`WXA$i9;T@8!H$5ain1$MJ2rj9YH%QlFK9kW^~FJ%!DJ&j z`+Cl0(%v6eZixS}ceAU^-FM?c_u22Ht(%>@aEb56_0%T|f@p+n$Uj>w`I6%dEGs%4@PS?Y7Qsv#qht5CXGIwa#YM1QFMx>Wa6 z+8<6Bd0+N+4@*ZIg=QtJvXVOfnndSJG)qTZXZE0;1tYzTI|5(q5)BqL^uXj~DTTO` zxApt?p}v|@xF{;3yQK<-rFWyhas}GenQFsRCwa!#0$(@~+&=I#WCG zlUz6{h;=C*dkhP9VX+zqO+7IzoGdcGA9R0x$`*TXRP{~#b(u{*!sp?zY9jFy49enI z=JG6OIQ#iAs^&C_u{DcG;|{O2jBv)BMcS+>B}~^hE*24-YeCIwm*a{j!1~n_ZAB?} zl){l2y_suW#_WN&QvG3jg}<7F)!3%Jrz;=xU-iIi()=VJB$>s0&F-$Ia^}m|0Fk^8 zW+0?Qxw-8(v6I!eDD(4uV&iV4wM0@~qp;l_$c8% zjD|@RCi!6P=-QJ;tR}f$woTYGSGKvat^i8laek7$87p^`-PVO?4G1^pY5xLdn|r-!n!s)th;`!lvzTYU25&$nV$!0TGAIvT+p6%(VpEl z;_IPZ=pe{U50KRr^vo4xt{w4pDpn@e`gwp;33)g#_e4254By%;tMj(E^|b?$fU?+x zl|7{THF{&uByCZkO$*S{=tn=#VbEu^uFl!-dEc4}(%iL1&thUxTA zEZWF(XX`d)oR_$5NDm0*yV`#+U|DMknF%l1YcC%TSQaU7s4K`#4_M|P*i>DRdo|j1 z% zS6C}33hLL|OE%5j`Z2iwKCiVYppXSt>WSjaJ{E#=03mbwf zVmtFoRUupXg;&a3HhDa2_;@Qsj5x&h{d5H$e_AWakX9fwm^7KrL!`No0uiWmAO#l#hWZwiBfdp#rbaI+XC?1Cn}&qu#x znCBVF69gW2aUKS%{X0>CW~0nrRh@4fy;qaEXH|3Ro{loR5GOYWa)suh!b+0?#OxkeubNj8X#Z(qHmrP!F;CSsO zI(crbjQJR)4Rf~!#kdy3{q45~ZK#Zyy!K8pq!sW(SnVd#*}u4yN?#v)H)>fF8%$rO zjk7HD%rFxgFu|UtHOB=rfs-$Oa-y|lvG($@fMro~C?fiU-oa{JpgoEx`4GJ$Uk6l| z&odMe(LB>@yvaVU$+_yqSbbX6xEFT_K=gT`KeU<;Ox-@tYb(hviFQ>&uo_R>LOhhZ zW@*M(i%haqu-M$>8TGu0hf404USZy;AAR0#u@K`@eV=qZA;#spB?v^!GRt1@j{=_= z^8ejd*EGHK4X##gSucDlwaiF0i_GsJ?QLv3cfz&%rm2A#^+`252+!1Rk!pRa`tvMe zi7r>7U*X9~wanvAI#^Ef2(h$VEYb~EjS8x|y?6!>i8etr=Bc?-7&z<{Ee>t(-?=R6 zk|-OP`mmB{k#-jn)sp9XBZLYmQDnF)nOa>n#<%>EB_(DB5;eRf!p5hTM&jX3SlTq` z`lNqbKOeX-1iw8^%3Pb$9%|8ZgO%ZgL80}r^biMeSkYygXaC5b{N;@kecJ{ypE*3)gwJA5C@JhK1 z3~ULXa$i{yLBHzqek$B-83Nm+8q4-x1A4ddd68d#bfMkbBu?Fn11zp%eU{07?1;?% zl1__3WyUqKJo}%e#Gr0hWKDqQB%=i=Z`5?h^|ARjK5Np84Hpx~!P4NYJ-aGO{!ezB z#*gK0yNp2B0ygM!p&N$WgTaMW%c)E@}}ngQ=AGWpP6fAT0B1OvLboV_D=p}6BAT){FA03=`qKSHZeZg?oL z6F_upY$QvFV_=M-JorhiU|9AANP2+FS2}78rv;lO@ped{Gf@#xB+pq-1UHulG?^L=}-BaF0m85<*IZc=^IhqJw_mSy#PQFcDpe+!jidq$?Rcke27Dgi(ZNE0R8dBBPV4(<5TAaF>tz1&o+ z1$Ibd15&;9HZipAGuz%)69aC z-#JbBOu3ERcbs|fr{6+q=Y8Z81-EP&>o<$OM z@QR@G8Jq76|DKlkZ}hMI!-{!0;rIp3`E?l5F6!>$mgVSp@oq&qPsjX{@+(3-C|*Z( zEnCI^71qGgddDR*apIRYq4X)AdzF~VWbZ@9T zbHWQhXS93s#1w`e202h@{Q-Mpy54s)8YUN z#FyDe*?ihLG6!OdkTn%C375!ucW67`gZkl-ixtfU4YoV*x2NG+IPL?M+4!pQIMc_9 zsWMTA+;oQ9H+fNKil{R4rLf{mzO=hsYH>tH+sm4Vu%PoY;t5ZiWm+bBHtfYo)ZEER zy~{B~TYltBEZ~`Uf*3XDfqAahE;lj9pSuCVDuDJhhk%kRj;kkiBFi%2cr@`Dke5RW z1gVW4s+znhY9dT(^S{l6P!#=E!XoN3%SF!|h+6JI{!@K*sHhEGE{#=BtBg}aqS0`3 zzh~-pf1O{u%UDgFTQ~n*6osTV#cq;9U zBho}DM#Lm+m1PkxiU>#USST@9q3ovZt`yS)%NWfyAc6>_^z0hMW}ibdq%7`AlC#t+ z#x`wpj11g>dst!qrh~a(x^A9{ci={4;dUG(Nginh{{o#hyFu)v^+XhCtgMs^zg%+s z3PkNe#zb;kORPX_YtSkLu(Ip`X<&4)Mf)+6UtjXsTG=+#v?=aMa>*0%jV_D~z;lf- z6n24QRe$08z9{su75T`?pk0V;q@o)EC@TT2F;hFlG~3iuo$avLy-L+hC%!2pO@Mg}VcdbzZP9j0De z@O$mX>VkExVP*ehn<;RQ44paL(_~023G5nK3SR_px`+03I=HCmugGh?Y8xV4Dvkq( z=^mrPI;=s`P^#$=sEf<&AQEPU;gO$l>Rd@-X`9TIE#>APWCfp{dT?s=^x`?EOpiJ!T&&$l)g>CxLB1zb2dE!T4?kzcdn2+fK&?UD z`{iZ=k`0mEemWSY^Gh9yC=Bf!p13H;56n%6jdsK0ksVA%nXg=)t%H6A&pWb|uRZNA zfPVq>j{}_{{w3%#Mxi7YrE<;J2ppdYolc?%SE6`yI{Ddqt3{TUE~2AwWIb?U`7 z>}KFZ%G4=-|2$GeA*xP^3S6NegT9b%*57nre8$Hs4*E}%KRzpa)K6zQm7uP?m7sP6 zXmJT{Nph>=W})ijh*dAFw!t>0kZ4deh9Ut}(gG-?1g`nOkuRi@VSj z=LY5?a2?&ljGb;8&Kfjiz%6Vt&Zz)qoRS_)PB4UZ}rVsdxj z5$i=YK7_1Df1dc2J3Nc4v7372z*WvjHHkTT9)Q><3L;(9S+MS>P}hfr*#luxZMbwu z%+m{m{c_7?PfM7nb~sF}kKmXMe27S|7b%BDgAOmwV5gk$9~re<#>%g_f?eaW-MXKy zK!~u;U=WSHBOOSpecTu6L~Ur9T}0JWew8Iyq~jVnDdr;6VkD^bk(jO((VFs)z354UjkxY%l?Yzmn!(vpCgJZ%e0qD%50^1Y&>g_2-0DDD9wS6^u%6ys%~m^GZ{QU6{Z3x zjQlG344jq@GPSWJyc97`4m99+&{E;$@dWrjOf5lyf#0;BjlA|p&Ihkn0&R|xA=MSI zZamDTsMCj*Fg|x{<6PBCPorXfRT(KM6WNpav!(unrADk_S7M1A$pwr_3-W z9OnvVw&?`)X$>S2=bnz&T+g16ya zBk{Pgr_l;so5b{!op7Y3%6x;Tdst*Sx}R=f*wY9F7#oWAzItjoplfcw7gs+cKx!^l z7#_#zU+|1?VaA6>S>Xh7C+j~d0*y=6sfO1CP73prxVA6_FdeI1&)V@wekc4-+yEy{ zASs76Mq01Nk7A8pVi7IFMDVd!;IwJ#uy>Gc6MuhouUb+;6ud%q(d?PB8-uKahNxd= z?cFcMds#aoU7~pBbkR!^10$1w0b5CyDZL~TY()A?3=r;#G%$#OquGW{XcsNG>G9aK z++=J-WVfRD@JqEuvLI@#&;PGq>3aU20?n^{EQ)1M506%)FQ<(ksB%0fY{sGTEicUcjWNE5Kj5mCY zjd{h=l-M40#KeVVL)f#F!i1$KGVpw*tf@<>q9By7Env_0!J1wKPiW7Y0);glKAr^U z%vXY;n9%$e7fS;6mlif_sd?v5R}NnD*{;3N*tM@s>>*%ofDToKN=kJ5qSb@VT`l>Q zh5iE8<&WA5{P5$bMgmfs(V6NN<%n@#+X9EUZ54aR?$$8{m>-au#S-RlUx3#^VCMNA zWu4crxXYY6W@+P@`a~8t%Xk)XJXIpfXU*@QvAkD35W+XSI4>XkHIB0#7ZT8a^sC=% z$M4ayGw$|Ca31q=3I~{!-u7wkh2kbab=V%pu3tW@WzYon)ETxdH~k=*D8{B~=@VE} z;NSD+!wjja3LR_eLl4w`bi+f1u_z`Fw>A(Pv~Fjc;C6|Qx+k>=0z-E;mAtP_H<+MJ zHJnYA1d_8=q4g5BhUQQGA1Ip&#d=GBnH>PztF^n8k_a!_^@`) znpbpECA6w^=-belrm%{gk4_R`&#>Bl{2)~4~I39%@boTnO}x%}`s=-)7%(mQxr zt(@gE$t|pywG@uyLtrrW_?}gHxs_b zKvp-J@D)IB!t@)Q7kfLVWvAE!2>Sv(KNB@~m6g6(0(!N}xLbAI}JbXIZ?1en@$nz;L#*klF#)u+q_v z7DurvvBfd&c26+BVldOEbH(i)`()%QT(~CBjjyIBR>o5Wvt}h{&7F*w?K`@hB4&zr zF?~KKwJ=nhAJ}$2R6B5OZC=3bk%v38JOumN&Nn)3*WQvR#iO^DF)QNQ-t5d(6SPO-18-$UKBy-QqP;X~GX zg*ri^sgje2`0!`rRXM>Po?+)`c*OV&bET`d8WN=BqQSg z%r8I~Aoyxf8nE^w%oaQZEjuZZK}`ZT=H$4*5zVXiuuO3`PFk{7^d(5lty=T5uNAT# zilWM~uj9zR15?JOWU6}-QaF+xFo@7|8t*M`YJ z-X>O!1Ou=17l0fDX$aTT#eLCn!0&+A`L;Wf<`!)CX6|C0EgVfHZ=Gh2l8!5I_eL!N zJsxHY6XWH?FbNvXKB6hUWyFpcRU0iWL?_RZCmQmE$(8$>i0vTVH`KZDIomrfPWX0? z1@Uj+YH{n-=RvPViVMT}=>6OWlR^UIdjp>&749P|WSteOAGKgf*KUeKsRI5OX5A*Y?sfd0RgS2M;`pD9LDG5g2s< zC7xJQkRje9yWkIft$JTHh#*AiD#Xe_jFBn~E$3)1rG@iILCBs9?vki(@P~NbUc9dEQbvct&wRp%N{imq-}I5*_te}(lUGv<2azgaZso<1U{H8K z-4!=LZ+6Om@o-v3&cVk_w)dP?n`xQ@ssgn!=51zKT(sQh8kq4CYfH2qLn_Ucg_#-M zR3azRCVPty^&AxaUeoP^i$?;sYYRX%0~PF=4wRsVt}y0kdstgRgLY$S;kAI=7Z+nf zcM9D9*&%wu%$TrutJk#BD@4upb{CvaBooaTK&&-%y(c(7l5x!k7ohVXxrZ45RYlaA z1~zIvwQx9IJ{;-or->qyMaeaoIp!}UVKHxuCEnav;j{jfpZ0ixob(x(nl78@t2}YtWqOV_jiM>WiSnb_sxGgm(!* zv?labDjNjyTwTF3I8>!5Yt;Gk^+F{G8V1C3}-=ywXAAsG#F_m>Kva3rtQjMfC& zB1sDywHK~Ivn-8452ycD)6$;@7oOqa-7~rx(NnWQ1717br8KH&0d<33!ai1AX$5~?5= zP8bQuMI?xn`Wz$<5Jfh2fzkk{+0bT5Ks~b{7OFgJ-}(xA7g?jRv|^6s9$x!R_g>fe z#H{Xs6R1FHT0oMGRV_OegV&&G__s&=w`=pGvZ!>vmAM=I1zii{qGz`{ls!5w0TX6D zhiMpnL{}7|7Bxr0HQ$L7sj~v%BZR0@EljykuO@ygGF$8{&%hU&qp(;wX06ULa8qho zhE7*zNz0{%V5zy^GP*zlN*uLXM)e$6f6wy7^e1jCEXIdPwm*-iTo#Q237P%`97oIn z2bEZYXa>Eu%xN0Wgx+GA1bkxiLcsux@j`z{?Z;K98m|J4F`ukLa*lHR1H}|gSDWnG zO;p_$vsF=;8zrgIH%x0bDmqMD;(6!jZYymkx%?e|y#elMc*pSzL#1j~p4$JA< zm>DQ+P3lvH{$8DDF5chxwSk*>=={PrYczk%N(hhyzrOHamPH+kIq~NkbAyJ6%H!Mr zZ2#8}qh|X#reyr zJQp%EW}hb!2FWC7(^%(Nfhv*204ruZEgkgl znqUFXu?zlPEd8u>u-O|_DFznUYEl>}unw)s&wy2b$aR}(vN%U8*0!dnHLx@i=w5%K zmWzgOcc&vmPqmM(&)i?dHdryD2_4*9Y)v3&rSB1k=fB3 z;1b?jjg{zV0}rke?ahl-U2E!u_V9mM<1Q`pr>6Gr2Rji<5my;26!KJw&iL|GnpCAu zPz8;ff*RR+Q$&Ir9M=>B-qhvm1S)^Eu7lr&$Up()AXQdrgcwVJMnoJJ$cm-%MQzC?Dyixx5cfdQzwfa(}q(o3c+=nBAyBHf{@hn>+|MrX87 z$hfV5=+Gm1s6(@wx=NnwViM&}T_qU`lIn1k9$v)ithm=wt3@-Ni=}as3i<7lV18+t zdZZ~eI!@&;NZ@PxRUDu+BTpCbXU8f^qOyw%FB%u*zuCt59_0>BL5`ROIO{>^M)RR@zcZU$bpI z%Q8Cn*S&?F9;t=D=ABT_->&Uf@U#NU#7&Vplz6I05*dp1;qOrRjxt0nhZ)nMmoTlF zSII2Et-9vJZxfe~G;Q}*UHdG?@@^yv4;WhxHdru|?E|pFCOXj9C{uAikdi!AX)Z7} z8v{sM6C^0w73-ZNRg;45h+B%Ak#Fqltz8aU_u#Nq@)F@k?cfT>}2=8 z|L2@@?|tv9ncwgKd5&|>UEaGq=Q+=MoCi9G)A+jky~dc z9ZxyQKVt&enn$9KSV>@GY6x;{hT2)e7C!H+0l-;U>#j%y`y_YUeCRn=63-thH}3B~ zn>?Q*^*j8b(f0fN-Dhu%|EH}S+qST;p~9G+FQg#LJ@%&|VxV|kcgM~~pbnPZh^@t) zBi7(3Dr+FuKi&?051N6F!4H5~8wS7&0{*dgz|@#jcax}$vO6*HO}03RU`6CWvTPH~ zK-6F|oAa&m<)!kRxE7dnCWRFw7+C`@E|#RD)C`7Z*!fBxvt&A}`LpjpN%>GoIYm?3 zapGo*uYZ2Kz>SnLi>^4rj&zWa2jdlSr2J>@v~@E{3C3^mEn9{jZFBk~_gOT{KZ}-v zC$^?wl!|)QhkRiJA}+bRV+c4%JTMaACti~%moZShJ`e_r$()Tv2mlfNo({IKyu_?` zLiPqdcG#LDkkF!^3uxQ}_AuJc65SLJiss1@ZTuU^ zE5bX|turpna21SpNEA5oQ5a{c;CCFba5@PBLN+fFk6GGj%XnzlsXQ(?NU{4jO5Hn2 zKN4w8%R}rUM&8=rvBg4^k;zQd2W(g>3l_tNSf6*n_fI;S)bZSgaWOx}o?41p|Ivp6 zUqpvv7>V;wflCxw>FOA&b_DU&5jxaiQy!=@@iR-spVU!5MGBr{ST&!xuul(Tl#qm= zdyI}fVi77xc9jnB zj%Ets*yHayu{s|$u3TArC1l5gYrEbrFc`V>;ZN0~@!Nw7eEX6MCcJp%ya{(l;yA(` z!0jyJdrV$$M=#fA{m(3fzHa;*$Wjdf1IBlcLjVjl;S+)%>uZF^`q0~aTHN{^wQg|k zdNTG5yT`Ffi9Z||2F5tUXuuDvzjQv*k_of)Z?1M8{j+i4$Ab4yd|rq<1GX@Nm>ex6 z2u)diWSnVrVVb4H%s+*^Vay2}Mz*UIWQ9Bn>5^I80~}A29dq=E|KCxDL(hzshT|7V zO=J0vaYAqytW>=DTER%&(Cgp(l6k!gmgAv;l|ACc0}SyW$B>vKt+3HbBvKXl^u!8I zgBi<y$TlwsaPdkRtFZ+?!!|I3*SNC7Fra9GNx`I%K+YsSB|DJ``5??6sI;#u(pJLzez#gHm! z4!l0;<6!6@3Zkj0?-hRNq)~##cUuBNI)5+;vF%|L{pUNF7f^#4_Y%u$OP*}P9UUUZ zmw>6o=1Y9tm~DrF7JD1b2f#0lJvy|i1WGLRt!PdNj`^VPp*ROy*}|M36Doh`(8HNE zZ-h`HGjDR^;!^(mO z4(=C;yiL6gRe zyY#gUzE#`afBk;-Uw6$eD26C?A@zqVOpte;3af=~W$!0ns z4|=Fa0w16`59S|81W=JaaG6sr^5WQpdrG(&Jb_m#ncHM~Ki+QX{#UnotLLx!N_tK8 zmao>hJiXHx6RGx#N=9%dJ;8_&3U*$txkM8Z|4DqrI0XqzxteDK`^>Z))VPneYvQov zhjDObC2}2Gnyw-fxp3;GpBw+n&;!dOqe6{F?Ej@d*Otuv5_m9DNDwbrD(HbhB+92O z5?!Gw6x|M~6_jkp#60QeWKzcX3F@X34-zK4k?PBJr$!~b9wl=4Baz&w$P`Y{f|X4( zd_Nw;^5-Qqj$KMbVwHqS{%P)l<0AHZPF4j%`y@meb_xM#qM!Yn?$0FWrmmxB)3Gs% z@;l>vRJ4l;+emCdgomL2r6_wMj;O{lV5hXQ#vif_%|bw*t#b-$v}{s`Q16(wz|@X^ zIPm#{0OS9FU|PcR**xvOLYh2-IMk^$m!xq=9L#j!gV5;Cgbt09e|8U)=D(1K`HF%& zL@W~%kp{C)XU6{E56MIg=1fL;h zDg%80oQr%OAt*xF{f#}7e2$JLol(93DkU2padiC0kv3GmqiswyiO~}KAB)$y(YIiszd9cN;J&En#Aq|wSOk-2E4nu9TPRWXt+&4rEW*{D&Eym<5fb zc$A030x&wmX?4f+&^!WLlvR1Uc%EEy)nx8WwjW1{z9RN}Ih&W#@j*(Z8GI-CJbGST=A`U*5}hkT7NTMGUY6Q?`=Ga~u71A?|bxRm+h zk!D2#YAFBUBpwIMiXka7{0Sb=i^Dkxld--Cx}+}#2_lxi2C?n&JEKo@cq8LqQ{t7@ zpo@NP{DW?v3uO=7Ny41$8nBI|_WqoLLp$R-Spf-lI0K~^MxvzFj8SfgbL$_1mvCE} zV^gXwQEMpL1PzMJcKuA(71XUJGa)~-Yz1TmJy@}_z$YOxZ0VCI?I*2i z3wp*W86)WD$Fny1Zv#^}$qtM`=Ho6{3+B&-{2ko*1n%(AY%;7`&8deMqxUCF?V0Z$ zikr~0A)V2Qw~cI+Qpys917f6L@+uWI2duY4WXeP&W8_BR?`jXow;kbTzsN%go6f zjT+kEzwHSmoWZ+KDt?UV+6b}QClB`rDoF(FnzujDxN;ksJ;zvi z0`>?zkPtRopagE@l_CNGx6W7oBPq4vsnWim+gf7SLMfKY1N!|0|hkf=HM3ae!Si|AYE(7c9^CN;+lOfcE|wolsr_S|qd0 zYXMaj88|=lHqh6dqm@uR7mdimP+I{@kgXwrSYd)TjFh2$M{Jn`5@~^OzgaJxG}95uLGM4c5QLDAZ0?Zus_? zpu!vm5n$pE6`1Xd)dzHMt^rhdT>p#5af{>7vYl+aJ<%w zbE)p(D={r#YEgb?hDI>~kH$8RywIuSl<@!Ki3nFjkj=CX1T)+CvWLDAEpJ&w!{=Q8 zi(*IY-NZ?57vcn?&+&)xWO7GBk9(6Xvfr9B0eKRB=MOEq`>^hZT`Kb+ME~Ms$I0W; zUe@&`4XqJgm1!FS*3htG-rH&}k+ zWyRG%_l#yKCl7^6NDnnvKw*U5UF^iG2=4tA+gpe$n1KDaCC#IgZ{P2_n)(f4^yWDm?^-6r9_j>JPgoF+~^6L!^yvH z>QN%jQOLb2+nNesRwq1MTA6ze%3KBoIO{2 zmUEA~$C>g%3Gew0P5v|Fzf`k9*6wl!^;wqW^igcT_s75C1}TtQH!xz=>8DOY;x6b1l)ng^OtPXb{KtDm@E{#?Q* ztf9w$Y5)b-=m+RvgfZBeVT>t&;IfFhJm7RxL(kEHz=W%+?GVvRJy_# z1e(=JEmi=S#3u~M*vG6yqT##y8V8|+yMvmgz8VNhG?=Gu`$%+^0e*@xO*|}yQxrvb zlu$GaB7`Cs?9-U7rYB4V^8#q%KE37Q{#jWe+Ab={wwP|^lStw$VXXu2rX*Y9e~=?a?~{crF^GzAe~umSy&xdmxV9S{>2Wle3AmBF&CesN&S%g2+=$;z)i?I7X<(dleOD0);RsAX00V`X(2I(952%<(O=Ow({Y+ z84_Tu{-R}?z#$^vh_Iti5P~(mF&PLC(C70~xH~+A@EpPd6L%pZmae%!R|l>} z##sT0%J3(?0Nh1nWn~ecHk+jw5jwSbw!gdxphmBGc7XgMAgo0&{4k(411#doJyWEy zmS1hn5AuFK?XII7b^%Y(gSSeD+pY7aq+s-$?pFnVGiVXj z7sbfi%epM^-krY=sPM6BTgedcDy$fM3>Nat;Po@7LpBv~Uh*?YN{P(Nt&| zEdS-WBq~J90VzeKFp^cKs85b&G`AlBi4MXTq_6}UnuzRI0q~K-Z=s>OZhD%-mYK_5z!}tFZ^pvH}xd>$qQ>bG#O2UL%W)c5DlN=!z5iH!1$E$_}FfS zZ&Dl-=)`AT{^G`S&Y>(27FoV>lkS026<;Jy(VON!Q;0rb>aB<`esHI8;tcP6Bk!tC z>z$Ey_`lJ&JEjH9T#?apIbha$%>&I_<}R@Cs3V&%pPQb*uHbG|yjW z3Nzkw&y=q+)xQ>KEF8UDVey>BbDY+`6sZopr!qZjRhqD$laQnS4-!*rOE1gbd zOsSkH>2&WoR87xkx@QzhIUO;OsGHPmN}3_RUhRhN4O*P&+V~*?@}HU{{IiN_jjqGA zYr+>)Otbv{6u#he*>T#B5^HO9UkAE7-q)zAuoKo|S29y&rzXub6o%)2qkHhw%P($B zVe4l>!{xkM-nquN;c)AL1Nz}A1Mh^jPUwd>R9scf#f7gdvbhcBdwI=9&K{K#@dJVK zPS-Pt;^(Lz?({BQSSu^BL}j2la7As!)v4De1Eny_5fvKONr8sK5v-S-7QWo$<-Myj zSA5fR-OoT+^I+3==un2AfrLkfu7h9Y)N3=0=U%WnQaRV;M4{0Jwf8gR^O};xy{R%~ zmay8p8MAVmPKisV>HgqXG1uQ}CF_Sv*5>KHpJBYgba|ciNPzXkC!Ub6`rgZF!&wCG zT8Hsk3r02!r4<9X!0N_u9jY%dHQ3-(VU*$d?0kLpOYr|8jWOn;oGW7EgtK z@vB_1wv$!;Ii&mA>oOdkX$*FuMgr6%Z zxX{F_GjrC&Qpo|kBNgF=TVN-z=`x{X=`-O2c0Cb3^Rz4BjPuHYnNyut_RO3LWauo> zsFLsGT|1oB>-45}<{XK&j+fK?iX>utX3FOl&UQWm%`|+fXhXr6qR&XZ_4AgJ0`526 zjpNIZ93NiiGY6YhK?yC%!@!2uF8W89E@XC{z)OO{IhZM4*1L?bNzlq+unWR55h&^# zGg}I`ml;;Nd^KVcgxrAU5NQYM3HvRdN;NUL_g)hYP+3%CdO$x>IAF<~^&%E9Xb<>R zOto=d*&*zo=a;4`GB{IjuKyAtHmB!1SDcWWgRtnCj~c#sEur9bKPs=ew4vvJptlAC zK>=WqOV|sp-3_`+cd;;SHj914x*nk+w3aq7%W$xTg{r_7omG(%{ywL-p` z_YK5)T6R3RIOhTYZ4;vH1)h0t%J3dWOcSl=O}PxE1;U0_9?=#lhUCn(wT%}FGNvw= z11=A&QP4`py{M@iFr0dl?nSk1xTZ_PgT|4|1_3LuLVVf4&)5(2i&KUIuwn`}Dacje z$8t9V_f_}s@7}wGOc~G|X+aicyokpvKX<4CRxCPU`fkdqS^knDuGn7kU$JrERN}08 z$eaRQRidFV&^?Xc1WOBy31n3uZ4E2(dVaiLzVRsayZ&9&nWdN7wMP@PcGgZ4(fC28 zBPcFSx~lN}SG)I39Z1;l-S@L)Wo{ndw`TQH;q7N4en1)I*$Z}_#)sCdUz5_Alo^+l z74_0Bvc_art@_9VtXp%VQK zo$-Ap0>!m;os2Ms(9lgPm5}U>tDjl5A#Pyl=i z?LJd0pkcNYkd`joQjm`{KU&kh? zA$l;`g|hjqrO3h-FVl+FY%MiXP&bl`GW*&H*1vOEYqASn?-FSn*+K}W%B`}-B)-P0 z?`1<&GJI#IhUYF%7UWH)(E=Ne9@mgm9l z(%oJhd@DHVR9U?y6j$M!v|0Huh7D~=V$Xlx7z(VO%MEE!g;e>eTT&^z6xl-S4TM20lXamH?d*o|BOk zRYholA<(2u4TnyksW?8_m{^?0d4e6j0umPFRkcPT065Jtp)mfh;?T_zeOlDQXi2Dn z@_P#5O_8I)3BynfKU__z&&Z6)a(hvAxaO~zEGl^_oD3()Z2qOzjzmAFN_dhspY28d zY4msvuukpB(V$_&78$q^T#Or=&To=*P^&zW)Qs5Ey6qnnKSe`VKj4fP;{tq<09+J%`tE6&^(YlZ-{=#@Mb=XW={*k|iGH&(qGDm90Z+3Whinz&iY_ASYldw@O zI_zIBlp~4{JS%vpB3F+SyqP)8m3Vw>ruPcgm(iLdvLOx5#P}v05Wr z4I^@JXHl1IhY71{h)NquO6Ql>;5=ZCTAsGuz$Q8I)p47;v>fWZD)H0Z{p&^D464J@ zq-->b-26L*YSFHgjk|1?zT??yDO>lT`c-aJBcev?M*ZZ<)!;D^a-sebvsJ|o%hnlE zgDf;qLRfYA;Z1cg>e3>rrGo2G)hSZD3g26hA2HGp@JU@TKV8aJqu7nRBuC#--d01j zHn=)2s6M#bYxQ7!P@cSPw-LJ>>NXNA4C_)c>M#+@i7M`rP1it8FAgadUK~=`yb|~j zpsUlwA}6Y<-sodj(sB37zcd``<1!A*->7x?;P%^Jalao z9qRz@&Jq>roRMk`X|Hy>Ztsq`@Vx$XckRKjhYioGHI{poEF`6&*WX>US&D;lxk)_; zZQ6cB=B{X+(BVzFSDU3mfmOAX^SY!By*t*}sLswYs@}Og$H-3Ap+hUar14;PL^bp( za|n(?5gU7B*by#+9#&S;Fj6gTVCyRxI^nWuu;e-H*nPIsTX|Q<%JT!)qwR(lXL*iH zx`vpSHAGScN>0?nuB3DghYpkFsCl3xj8rN`DyKD;cOAHUwK*(MYPN=$n{0<+bwrws zje)IuC6Jz*d}zIqoqJ^(x-Y&tuE=GCMB>8hN2-~sW~7F-hmK*GR?(_hnP7h1NVg=8wc@sLL7a{9FKd(iH>&(k(P0x!g88rUT z75%ba5vZRgV`zEF4z38!Gq6Q?=QpK-bIf!jTA?wcuI)=u?f2R}BLiw)&R-W`fA&P$brQ|Z7H96Hv7VsVI8mkoE)=C53;fzOkQUip z%uU|LUE8hQj;gYZ?rJ#I#i?|eNVq45=Dc`VZ`9Hy>jEF}7B0yefer4lk?Ln9hqc}M z(__Nxy*sw2iBbarvNuu8o^byzB3lu^LCsx5D{gp&zsxiE&>)j3?9y%Yu_3A|Pd){B z)lhs!mzLNN(42eLygQTxZ(`>z>juMEmWU5>>`g<| zL+DT76z=lDfNqQoz$Rg!Dn@m2vRx*{^}%;FNK*_hV^gVse!w4_|99&&5h5%$8&MPX z(k&@V25^|eRJ9^G5!Io^hh^Pl(j|hWissv#{Zs#SVuz{QS}L(=zp@SyxFssqF{#g9 z30Q2zdTZgOkJNZO<*QiZg~?e;A;`>#FU_8@T?zjHpD%~KjK+6Z+Y$p_p?H1Aw zCn-JEV7WBO6VKG%vV~hWihetNA-zEsrH0XKqsJz@+#>&sx)29O=7R%Y5#?sN3Ijxl zW7Rn{Fm&eCLX-j$)IX&Ce7oyg0n36&a@$B-dLebtD^DA>I7i?W&PBk^G!R4P5^ii4 z1Awl2cd z$T!UsR*gUMqCk^7+RZDq=8i}k(HT&XO@lep-I#*XHKE~PlQSY3F)o{{y?+m%LuzXv zr7vM4X8V1>Glre86wkZ>BYS5^6da< z4_?eh)+Q*meS>e`E8bh_iTl31a_*=!x3u5gcW|*z?+fHBNi#wOS$QNXkeJIrRN9qr z5Zld=iM2(>2aKB{WbinGWl5YHoom*|WSo~}0MVhLoec2?(L)UKg{sul95_UC9sH5V zQnJ08lH>64a1AonpjyA?MtBm90ziZeyaHt#1G5AF#=LdF_3-ead?+%svjOWSMo&yE z+$#T!S^_Yg$URD8bb<3^32h;Qdjurg=u0djk)K5N0dxgsJy&gDP%sXTA@GG^L!SbJU}(?8Q?K1JIi zgY;a4E%GA*KZ5=TPX-#BxIt$OLR;X*AXKccJ}n=A`s(eWelRn!yg~x)E$^rK^W9V| zD{fu>W5PT6zkj_mTlLUn(K2P(Bf=(<5_z+frsWyV3Om1W;liCOHyNGn?-K4FIy+^` zi&?REtC*WX%Brl0>g~1?!A_{@>C|8IR_B3A>T#=&LWgEEkXLmg<&(w7%&J2vjXzoK z%c~l#8P^zka%s-*r*HhA@avo`Hk_+gu)X;M8)ANl`GGUTOQCvqAr>6{RI0N0_;<3EQ(n!9%ufeD{#|u5#eARMzSOKBHaG=21!c0K)e-W_>xERT zhSZQnyZw`er1Z{KtitKHPzo*r)IlLBNKvI1 z{zfm7nnm7B&QZpZ&WuUW!pR#n6T=^9QOJkQ)aRboTHJBNUn?4aco?-UBB;RUen`1| z6M^hs##e5do2UL^wSUI`yuVHy|McO*-+$jEhm=zI2;$K-5>~~yX>m^bvV+%VdrQkLI^6Z=DV;-6G8)2eV zypj?`(Fy6j6myMKH>>j9#r=zVH5WtC6~+&K{;Ri{&kn`BQlZ|T>POsZFoG#SeMvevhJ`8opqN+jo}HIaALj!p ztv$V(l$mfH8ji?|!eZoJ0~W~J#sy)*3EnGj8xuru`)pjJV7zyT z+haXZ+BheQmR|hdI@5q z7b=qdwdDrZC35ocr(woK4^QI*iixbTiqHgIOwP(>L|0&z0t_Vu_*mBHcRC*oCaz0= zvcrULaWW-;kF{cyWLw8R*zoT zngAIO#ZDUAt`E+X9bNQ1IY@ikz`83OQFKKy(2OVzUgxTJ7sszY7NoU}&bc^v!9NVc z{6zhCBAfkT134U#_c3Ez2HYl?z8BahY9Z7Vh>bId(_g9YJ#g^N|7fU+dD1!@hTAvQ0gf zQgjDJ00kuIG*gb2)pyfeY~B<-3<#YoA+Dn22&w`rj2LQ;Ao+NL4KNnqBHyD0ya(3fuXq90 z+;IajUOY*8jOt?FEGivxv9B3e_zweiY8%KWT#YJ!UfTYy_2{uabz`LqmTR+3T@zdN zN&_P1%7|~*E_sB`G5Q&3YF61S4Hxv@y07Y9E04r#MU|t?@jmsBtw-_Kn=APghkMAS z6I%sG7x_^h4T%x&TT$gD@sHc>IBosuCfd>;Tg&({ATbG?B|S<5j&5d}N2^NP;a9I8 zwF9nYXk71cwUJ#)dm2Je$hUH(A?p8G}uWg{aG6%*Q>3IbLxV#)o+y?m2AjyxvcDv zW+kLJBTbqHc(ZOJD)hV*^`$?KXl-W_rfpZE>p|oxsQa@DRe(QL`?W&Vy7G#G?4vD|R z)h23gjAeCe(He1;>>peU>8Ke=-KlM#;vKeAyX4^v8Rm@PWEN(L%^4V|JJGBHbSDUB zD*XyK)sq+BJR-?yJE|F7-fN~^vU@}_#(O?kkj09@1-wR{46oI91R2evjYciek}<8- zvL$QW9bFCNp~5YyB4eGQ3l(Czx!OM>><#`~Zrpi1iZ|j5xxHTVn)<~H?ofPu8L%)C z_W!rK*O=l|Fy@B=zvf-JtY^ck97FGOzV0h*ve8~9F@C5S^+tbmzYP4I%1#I_7|N(U z4{iitB@-;)8jIZr@$RVeYsqe)6>atfFuw#Ku=?CT!(M4#i|<$g31?_> zME7HG62%~woYI;R9h(&i{wIfzT^YySYyQ%3s>iG)I5TpuBD>-zK>jQnd!IU_2K~1* z?MDaAK$SolhS_(lR=9FA=#SNZ@c|_TXQlt9a)Ou5`%3?*2+_sA(jk6r;uWA{)m5U$ zrb}%xsK6U08)sime-7At6K&Q#FJBR)QJ0{N<*%s)T=+j8-xy))rx4-6ucsAV91q&6 zsF#8*XIsaOAlTn*bSr9d6%YBt<9_$WP(k#Ih&Ue7xZ|w>7==b1p0erf z5ykP$&K@wu#Ys6Nmk!zAX`2%1tI1Ygtc2&59qYus9%Fmd(oyK+-Mu9bHY-)Rq=$tZ zx4iWR`9);0gG5UFBN!=4gXcrE-q=dP(JD}$Q57Rgr&A?Kf#Ixp!Om(!M@T`B6o1t!F|xItK)_&eWVz5w9ze$P-FzlQPvRtOtiZPuC9Z`&9{?X?aM)Y z%T^iLVq%BX=!2P>_1Mguf?}IaZ!|2nK zSIX<;QNHnN<)V1e!SmQla!cssTkYreT??t?qWd$VwrUt3hO5 zU2jF%#rQjkWf@m1*xd9_fyVg0Pgfx=d{9bcwE~~Z*rZISj3^5}cNZsj#kL%1Pb8gj z6buT+*hJ>2nV4XDVvExMD5@WlvrlOyqc=J>GxGKx*DB*OI1{p0QQb>{U(j_-Hsq4+ zdImJWXA;I%{@fLDUEtFA4zG8YLV+jHcbP;t3?+HP&)YlJ>HS>2dj#G9xe0?ZS67|e zt4J6~^=>1EfN0+!@eooehE=ct!_{oP;ys0XLcK> z;ims=(Ha`!)+_H+pLY9;b4zF6)BLt5^s8Ubv>7kl_(jMAUEiUip%rtVh~39Nt-8TO%)gsXC%}$SQ3V_I=l_ zPb2-(vVs!}*z*jCy&(G&WjLtqcKN;K+Xt70aXuCB7VwnmpHA0@8F3K9Lhb-@u#fqn3RVkQ86I+=0!J4s&c*~+DwR_A z{IL}1{mFgmFseNi65iYp+`)tW1{(7ZHWLy#TJ^a7R5lSR3(zdG3z3;f*>e1Z;s2758qi*}T?tG%6#+8k-;=Nwc_fHTpeTXNVlfY-s)2CY zN!{ULz_Z5xp@W+JjTa_O6c{N8K_Oq+U%}`O{vpyXTJomQ8iFvRBJhO#g`Fa_Z4EYb z@l&~8L7;c-o)x<)zH&> zf!vY5jKUlsl!Q+goo!xtjzi6MZXS=tQ#u*17T5YDci?Qf&O~!L?}PR5M;)GgId7zV zyx%v&H32wSBxF}Vhi3gkB=;}Qt)mHh+m))aLymXZ#^vmlpB>Y>w+;CK4Z#bzr|Ur5 z=M|j)UfTdzMs)dq6ccWL-{lBGWA#r2koN%mFp!gc55uD9wCl(t5%~ifgaT1SSRlc= zMYdfu;W>OC1NOHFrmzR;gj{ThB_j2R@oE6B*xnf=yh|aI`?s#Y$^x{aSB<>=y=#_n z*&cXB*DM$md<%qbf-Q_ExlsR(;C`!5-C{(NVw*dV%Ml1tLj@WC7TH&$`IY}pf-wd~ zQRV5uJX@$srDBMi4!m}4;4+IW@BLQ0M0rHAy!EJN)Lh0HxX1OYR>o6k2v%&+YL+LF z|AewTbM&r*Rt0?aUh{{KpK#ao{qxowvyMF0> z#NX(-zL@8$!;BzSLA^!o(ot1v*BXX6inNMki86rWqEw{il7RcW>n@5CQ85^QCq6LY zRDAN~p%34D`t8Kdyx*<%&DgiiaWMwQ)|PXWbEEYpW6gTpPd>~Jj(Wo5xdOf-Uoc1ie?3jRVs zf;bV7k__frFba|4An{&B1U4u#K>lIzAcGQk&vb@g=x_t(a*RBTi*{RcPHKJngrlWG@uHd#DgEGmJfFHA0;i&m zFi#8utvJ|*f?ec^(7B&mA#@-e_dKyZnEJc`4YV^G1<*;ekg!Hs z%qy^3xj25+;G*?Ylh zI6Mthg@VR%9T4B9g52wDIJ0rcj2MbmUT-t)t-L-U*8x=iR0tO4CiirAI%Dit#$3Q3Vmc8ii^FG9XDjnhZh|m}js@MaffBz=FNKIGw-} z*rI6Z;`BXYU{bEPrQv2PV>^Ld3nGvSTh@#YEZuhCU@Euld}QQvbUnrOu~-4-df0pd4=Dm zeJ==Nz`q5cb~+0XTUh8wL;@9shY1ihxxmb65C#4zlO9%#{1q%V0vrlQOH+K{pXty) zh~ZfL^@PzI38R-1p1};D^4v1t9h6K%IyD$1CouExmjbz=Bo-()-1?pPom0p4flIu^A%B)xfGAehvI!4+>Q4V=^tXXW% zz8a;$R4DSc6ukK)aS{@2Y(eWudRQ0@6O2(ZXX@qv2XB&>| zuznisglsL|j^=RR5pmz4RB+tBU%;O`DW;;G_-5f|?dD|(6}_{i#F5F1r&*_;hs0uJSut7slUx$+$&K6yKqe_$-a_$6iR@}*#s>N$8yZ69 zI3z3ssxxu((V=BD-;l4k;h6bR6r>|DW(bL6qJh8_iUl)kv2lwk%{j3Izc0%RYO!`Wa>kax+AWCf*RxT6T^cBS)@+i^e6jkA1* zL)!4a$s|sUj823jIB}OUQqhD02;XVjAnE}U0*9)U_-3VJmhXoB!#M9+7eW|QGm7J} zCZXqBOkL;)pHG{AtKH7w)i;hkDHt>7avQlje7PkBLZm<5kpLmg(b%bE6`YEUHHg^F zjj2m7ZLe-U>e#2QG7@X9grcFCB|RcRc%}1}OW_biZ-Jn&UCK9FvFC*R2Q#X{5rb&Z zSZR-IdL+7>kR|ysHKQE)SMZDu+!v47<1n<&lRx_a*;lO_OB0c4bzRL&Qel3yq=LFx zmua@X+*!npkO_t-)dOF`7Nf?#He`Vz<57|h(9xEm>)BFdmGLgAd4!B;eYN0bZq-<0 zyH>K6+t-8DQR#7Nt*yl_VZvsn|G6Tzev?S_xxuL-DT`(&xxNT7UU^tyex9!0jM*-J zmk%b+k^8UNnR5qz`(o#u!(xBC7&#`pIhG8b@4VFeH2(E%PGk4}f!YM!&>auM{EPcL zTIO{MmJGFN>&tXQlq*{1u~theGi`r_nm$ngPK^A;VGFZ zVX;SBMcYIJzM#SHUc^!SdO`u{J@GB}-nqlu|zN=8$oDnj=^NM~BtEr}+gUU3twr9@ew7H~Ozp`U$k>t+6eNn1CmAa?y&73MBu(J?uiOX7Jgx{@t)|sBh#ljZoD^> zREvZb;mdS;4SNk;R+W9f)(kJpg4VntYqFq)Sj>db@+^Ex!|N8|6!iztli0K;pURGU!-P6;(n3MOZ>yo7Vkg>#C-YX>0NV;*RRdIoH6(DiVzvEFT*;Z zFO=3w&6SawYg}@=GX3(gFJTXwf0nd3RNM7#>PYukKDbv?*z3#qK&>SPgL@@k+qwKt zI6P^KgZKq>#L?w{%9+jPeP)~YNxpaNm5o~;pLF{{)Uhm&$g(9HgyYs*E#JH^chfO{ z`S(JcqV&tA-pXX@8w2<-VFP*@97%`!5h{{+El6q+FM18cU=g~7w!tE>kAYg82yOts zwK79uXaa5K`KNU@EsWT;05lgKP7~6{L*k$ayktP zwZAX6wxw=KdzRXr2ifb(oLmlv99`V5Q1*T7O*QjXX#w|^Ox-8s2o2o;UG~U)XBsju z^ATMwTA33vk1DJFlvtg!DotW)PU4>u3Qz?+PJidJW2er#OJ7E4pzr4ds~Mqjw1^zYS$piuIZ`2dC08oa z(GevDJ`a%Tyiy7KS1Qr+Tyz^BP-1q|uOIsoT|y3{9|!Qq1iXES3@$9PM+9v~S4*PZ zz5`Oj^oH21Q0M6idh8b&=4`A~I-fCDrV}+y=jyE&$~^UQ>aMwlh|FICm%!XZkXz)0 zD0e88nfeK^5X@0BSqmYXog$Di*D&XLMu_phR}>@GN2~nioPz61rdFn(I`-vCDQLFL zlL|>rgpowkTe_M)J_rO@RslOej8C##BElXltJ!we?YYfi%eTGGzVfOKBeJg&PX2aV zwfpE$fVpRX$cCfsFRZWGJx_$P|JVU>DJ3nJxRQc5%l;_nUw1h7&APHK?WV$4T|JrM zJQeqXo;hUEC}WB60-luS$o_KIwyK><`wNO(c;{!OHZ%{)=NBJJI58zaMbbfkr7rLl zYH_)1dP#aoOCl_`9u&Q?Eon)#h1tR9iA$tDuk-|#r$a02(Zkq`3~D^GkNAI)DD1By zQlood8g9SoFPVxc02j&nhf8hFh)&%u zv~(4JeQBzt^hoA01xWvxk-f4&6*okM5TIoWSzw@4pF5M>d8l_ebb;nShy@KquEe`UnNVJ|N2CpT8^=-!TXf`ti@qw*JF2&)YpxN z*?WwZG(LGYlozLX=dkN1C)Mon>hD+7Uvc$01ZuxfGA>Gg>pZFYWBqs%$d*{P~tfA{ej z^Tt;06XzqmYZ`T29qXnxUgvH}_pTR6ChbBxCcGy!9MtM_&rvcQ#CS*EtPXwPm#AEn z*X}tCw{6evt$R`D-L=F#{_exLM(*+iZn=-2M#6*wOW?nB?Tq8Nd^Biyvaqp#{vVnr z&)mGT;tg;YwXOsg-p$mbylB;I-rui0KV8%*zbQQ?d5bJ94hx^2(zQI%v3VZvXR;jX zK+~#{Jmr-~F3*@{apdy0Sr*4GZ#%1ASeH8mRGh~;|2_M}Wk?(J!i(@Ws;+KhD@1@% zO!j z%@h9GQao|7`v|)QF&{6y>-0@ zH!rH~&)(`UR202WRegWnQ(j8T-Tp78Pi-ywV(z@Od$@XZO~M>xGFqqohc_Kv)As&w zDqu&rH7vmV#YjnPef9#^Ek0*oWIpj&&UMifJyMq)F5{?H6eweUxW2V2T(dmW`DEqH>)M(>4rTYhzUVozaD!|2gIX{TO#eU&!+ulo`h>z*^(lB?fZ+*O5Rn2|y?X3zxFzL&ybIScL%Rer4V9htu%e{ju^ zl}Gd|pNSnoEG_owqr*=f4qQ~H4TP^RZs@JP<2#q*U4Gm0WbMvBG(F=0Np?yJ(7ReI za!1!JINaFQF!zpUo4HQO>rStZ^rxW7U3!sL@^!LJ_>U&{S3HRg)cR%F>(FHmt&gAG zB+u&DzMx!fh2&GC!65b06)yeR`!q);%3a=M@3YK19;L{!vX_o`aciGq@7~q__M%nW zpuAOUXt{Uvn=XA#BLfeIcS0M4oje>4ygAlZY?(J5Op*X)ZyDgE&3$&SuA>1pxOcEY zpDh;P*jh%@L+ii$nNlF)$E`!WL>d%gJxc+7n@?ze;^M3{~>pkCFJ4IRlL2Mw%T%_na z=o3{JeLlbChhB3AdwqXsgUKwH-6SLtmUd*M_t24kg^T;jtP0A3C5|=S6P?or#yNrL zqYCX83=o*DBp{i1#D9ORpFjcLI!j0jUvTWywzC$;u1~5!9}z5o3r0b>rYBdl>|pOE z5JQRkk?~6W7@+vh&qS5z=B-Q{AIOBIsp*rMc*w3VGX>+ZWge(NUn+`=S~AHtn&ibUllgAtHb=UvOq<{JC^nWvC)}CITv2RR8GNqdnBf{kmYnnkP16enyk-T)Mh9#GSR3t_+`$8Y*+Z_^uc6LMeFfLB_k=kao;I`#TyH>%8&9MFX(M`FNor)77W_+mfzuV z#VI4Wr!v@i;!NX{+q}9Vm;RCDk)O1@JC$JV3r=s5flug|wU4mWL6<-`x^#1gxEndX z?`jdIMt;=h+H)1C*>n6r`@WnUyvhFXG_73YFbLWXTUpqUC zH&!reU3BJ5{f|FY@Bb-~+E9$1rn&9aO`DE<$>CObdA^b!0cE($z37puowQ``!1MCH zmd4?++}<02OHfj_$B(_yd3aQ3WJ|+i1753jYscXJ72m~A$Vj*D_Z=R~9xwhTf7y_A z{(XC1C9m*F!Ej7&w7qZNEYEUj-gga^qS9mT+~r=~^MD>(*4K{@-sz9yRY^Cc8#t%B$Izdpv(Y$2(SCn7Amfn?3#eiT4wo37`D7lExCy zo`&;0JjPaRI5}`<_;KT?tXKD{#nv2Z$^ISp&%$Dhy?gTeb|k!=%d1a4rF*1Piqq5O z+dIp%Wup9)w_V|mf9fi{IUPM{UDdWuJB_5cMg2j?cBa6 z32iagDwQ}s<+r^{5=JM0RL37!w;b~Ao@;tpbL3=s-yb>y(=2`8y5uh#YifFsz?;5- zTjzXlJ9w=qM&4YtK)b|?R~+8YyEe<(D=M6q9p3ZHoJDguV1CmV3E1Tx;HBm0ON23o zy2o8MQYH3MhtfCBaLQ1yn6kz2o~4LhmxEYjY-9WW0v@mDvQ*vC$emWHd&HdN zo>Nu*+4=f!l-*uE zt=;T*zV}1E#m?UEqW-8m zo-@`k?CP%RS%IpnZ0k#qAj9K z5r@7glEZzreqq+P)nD5@@&BiW#hQ$-6QgIRe0$(WJ;m86vKf&T#?V;bvPbrSTw-+b zs%2)=7jM~SD$3uu94acd+xH9(Z$tl# zjh5v8TJGDStUaPEeIYoD8VpsI`K=M%K36aD;!|DRCeCfB`Xt}o|FqzfO1MwS$MJDr zZo$Y)j&Fsy%oPPefOjjapD0>r^{J%bnbQJG_a|i!r#YW|Jk8lBduSpvp^sZIdicEC zkK1#;zN(=7-^lB$5AQTBd#K2Lqc-u-m24TekR=-=@V< zb}a~FEZJi)7>t?uf6w#Gp!>eR|D0#ebDsS?XZfD*=ewLo+rBMNZl&$c+BuQ^gOswb*;C&* z2~$Z~IjpgW$rF`PDk23PVvW)x6@U=rIB^a#in;GuTCk>CXyEW zrc#L`i^%FDv+wzjN)S7{d9SERiG)dt-#12nsTpBnwNl^qLB9bR?csoTWt-_sH}^N0*H2FF7RY|}ecq^7fF z8x4~wvW zaSf-=-!6=%yYBL_QkOvc6U?jjo5(|jN4={3RQ9zeHST(*>#oMKeb(v{j-40MVfWl2 zOF+78V{2y?^E2sVdRw6(OD7%JGP{agR2=l*LC(I`taE#A6jW?gvbB1c6SiUMx_Zv# zSZkhX)+kX?O52UWGt`ZhRQ!ew|gLwwyGHhDU1%KdF- z$CgEgmm}}X#@QBr`_A1x+R|^F$jMilCQy$P$bsg3swyC-h^{8dtGJ)Ol6tDgkRS06 zuFZu*5WO+{RetTWQ_mx7Q~&qd{hwnqf7r$eo~^-AG~65$J+|W5oaz(QBhE$OGS@dwXGpi@7u%!)p-(A-97wSOCW#LDhvknQQka-V-L|(x!Cj?Nbj}*&UrCQ>MuWk{4dPsyEZX zH|3s61|AJXRyz?PpE-gh9#BrDM}=ob)|&5ZG~93f;jBCq`GW)dZ$VG^A%sRBOg{y* z9OuU%hCZ@nSndO2GAY>TJ3G`T-9^kDvSJZ$*RffHF$ZfYZYWrHXI44JH)&*fIQ2J2 z|6%l8u0iy|qRjcQUzn!h-d{t}%@TH8->8x9akjsvE;v_ALDbOzHtLgXLp;|v{xd=Q z^UreoM!4`DfxE=1Yw9*Dms9IImM-dJwMdH+lwf`(!Cc3rKS7mHX_f_?aWA<&bn`HRi>*fZMayYel1*`0{h~wWQ{0h2x-x(J@*{AoBR-hXU z*YcR+V@vw=f_+=2S0(3N9hA;BO3ssQjLi0II3t!ovN zZTIB~4`{g8C*>*9eJlI9x9M%YQd3qiY=!G%+C2m&m&tBda+zQ0?2M#QjfGqR$=@ zI;AejIwZ3y!>QO&ggy{V;O(Z3eb+5K$|@MjuIIAp8)K@^a(MCDq<1NF)?rn*>VCN#NR#f)sf)~OCFLu_N(XQn_&$Ancr;U*Oe_N^g zN|39r%yPTQ5c0iJDtkdpD!uEWMxM`y2Xt<}1*g{8buz(WJYCq=DnyI&uI2X-xSOw4 z)(L0e{drHdxVFwWjXI2OmD}45>pFwJETZw#Vo&)7${$&mX}My)e+yB$mT41hS-bN* zi^Uz=UogB1fG0~2a?+ZzRr2a%a1e^E?_T@0`}> z_D_8h@ftMAFV}VUy%HMJUS*;EZIaBg9pvgE;Chnp_`wcj{as9$tU^~lV z`pOFG^QR*GUzL-HGPM$6J?Beaw_cR@+sZsSlzQv5-V@OXlm41d(CMF3-en3mXWNKg(|3|QFs_b6IO<&<{%rmA%C$r?XLP6qBV`|#32l?vTem?oMl zmoArXbT+0&aSo+hM8kZTW}KO@L{DnapyB_H?&n<|TFtQXITq&+QmdWyfuyGqkb59?9H=?^4MkmO$EMPfZ) z*3&|i7KO-_+yjg}VdpKh4N}w*PYSEi>yZYsG)oOXKspyuG5+l$5s6%Z??ETKL)vr2 zKqU6e@9>}%d0}S}#RIaZ5K4o`%JMUWy@5p#5G$<_O7*>R`?$UsZa1|b#@weA=v5J% z2joFrGNa%Qn?B)cAywFvQzrwUys9Li?OP1DG%-CfF9}GXXuw!$KuPbbM2lulqrQj5 zrc{ClwN-^Wz9`Y3r|)i2W4qTm&aY34`Y3yYcxIuKC)yZQlN#hHm)>8KstbhspF4 zAaJ4uEe0PljS%AI51RZz)W-IA@je~f$8H@&IYq&cJ0mQ)y2M3M5co&KZr_gzG8eV_ zP-A$-d?)aSQA;VOOh4R@+$$Go_-oYCzAhbu%VkBSD z)-mAeqh7htn-W}9q$Wd&M^6FIadk_o*4TYjt_3eQFTwwP%pm|$E#ICHMwcO$7QSm_ zydvbPwaeJ0-I}ZvYPpR%^9XIYVqOBzjo$x#ynN@o)QacwD&NbN=I!i=K9%1`_l*&1 z8M$M<^3K{jYhz$=o=#-jDY2t1*si&(;8IPNePPqrFGlD^`$l7x5F^y>)O9J%AAxUR zI#Yp%s{oNge@m8T#~JPE+l*WDqvl7g&639XUU>borIdaXLeF(_8=E#+CglG$sFd2h zK#AwixVhFUHYp0C;ZX8O00@5GR5p*jT?vJG0GPdvp$Gv}vb#MZ43p(Tqh+lk&lb1OH4;J}j3N*9$4!U19-eY|-Tf$)a(W@qz)DlV8}^RGI5)NP!4INYQzXB^3KmDNP`p44e#2LY z4adc;5aVTE6zt^!V!PX0&LrOrb*$WX%d}#j^2(+^{{d6crc-6mPWz6L^%l0i-z2lN z{IbePHgdPr#KjRR0!RU}VI%?qXb^k$!#*5lERtJkC@Kgcvcd-IBGmw1^E=B-ulcXU zhwx}jWF$E8^qC6|XVNRe`JD`JIKr`N72%m@_FJnwpu_@T?5V53VGHHdmJg<~!gD$v zARCthzasfBU*ZW#Og@K^h_iqi{~;cY-3wT`q9$rBhADf>FsbtWQ>JqO;)nYS4S(fJ zP63hf7yPQDqBD}vRfwKmNsZkrCkPlx!CEzHOPFvIh>6=?)B{s3v~(tVOvtah$sDsg zvM8X@DSAWmvCY+Uo;@v_}|P@h$ro34WNpzV@XoH z1**)~yAx_DK~8d`={rICw9iC-wZ1}PWvfX#3oBM#_0`O%l>SFysF z%WSua z@AbK{_PmCy?D2_$LYst%^%$md-33UL7R4SMy{A1c(xPAR7>!;XVj_s`oy8JbY2=DZ zzwc6oiLFO3n}u4}ebN|B7Y1lm+{sS$9<@zl7GsI$(yO%TddVK=7fN0bX_>c3_p4Y1C z)$ZHUQ{D-nESslbvKv4Ix*0HK9I|)dtGo1->=NuB6;6bp6Uwmyc@3 z7k~MA@h>)pD=0rbRCt*FpFIVSO^?aS{@r5Ur{^qxOy`)};YEgu+y46Hmo}Z%@?lMz zmY0sJ-H2&; zIrz@;&BYMvnbGvIy^>RHtRb2!gQfY_U&?>;stv0)EaxSv2`%jYscqecxOqWt|G8*q zs;0ChPJC6>5^yDoo0k;USySxVb3*-lv1F%uYR(H1(j*rn5BnK`ZDNnK$9&kMyqno$T-41*&?%QGx z7~ri^gKXYsB56}F-mg*oWk7mvgc-u4hYRwD?k|3cw!C3kFwGQ;dh$28+b!p3DEXrx z3wi4rJ8Km2e50r1o4bS^(JNqIQ4is7xSZ{%DM`An>+&Rfl|}pYPV$5n-kA71-3=3qnR z84vo6?sf7Vl1!z!?9Ow6oVOp5fE-{&gA$N0>|4ZhEx%D=W0^yrD#o8%j6VN*oOHOs zc9o}iFij6j3g?w4wZqGLsvlkF8S`$?wZRs49Ve|lO;Z1^7((lOt`Op=UgY|?)3khJ z^z3o|K`0x{g8=h?L51e2o{p+5W8Ham+&N$a-%9{9*XKvGW-8#;14jSIl7CJFo=6)8 ze);%gbmZr`JNRA>_({kILGTy_%uWqG^W~g7!UJ%Bf!TfNihb+0DMB#^)|)hYRxev< zH#L=oIYTbrR;5%}=0FdKeRn-%u;UX=8CWJG%li4(!o=;mqMWtMEA5Hk29&Gz z$-B3`qOGxjbdeF#^5$LQ^achui|~fU=_FLxMriMuR?$IT4PZ?WjNIE6ewH>3gJkd? ziC-MS_oU{^9_-7~ZF?ky`K~5&d_<0-!o+GIDOy({#7Y?aEq>U9<3&;JN1zoRwb`a9 z7IV!Ad8!pZM7uhVls}9%Qm}wl_;t@8^DZr$ziW8|mRPmRv>`j)%<{G>2;Sy@90B)s773g8358p97_QH#4T6NX`322<*vk+7p;+ z?8aE@*e2s%-IWE_Qw5PUYjlAtJ8SZl?ge?wQ98@N;@fQfL z%hltYs8uX(6ybeu6`u8OJCt=3?hY3DyO!F!H*2@VU22adP8_nU=1@BZD#rS4T-BhY zgh~1RdsFFdfvSCl5rtvDMB#z0J!NcH{V8$s(Bh+W!n&wW^8aV5bD{2Tr~{irN#2+yLZ72jQyfw-$zX5aUq}r$~m%c-PF0_RaR}9>6S0 z6%)w8;*#V@s3R7^5ZT>e9==YQx3D1y?4^dht1&aSha1{jpuF12G^y7 z!WwBvoLJEk?mu>!S+45+&iEahI~w6KkkE9PZ?){DMWS|ZENqhG7WwW4bH41Ortr(( z`11nz6+c|Dc>k6)Nq+=gUa{DCUU%@P*WPXae*Wg%AAu`&foDtVd$F9qY+S#!p8G@G zWFASr$Y^;ItMyNB=)gb3DaQDEBm$A|V7iaJpUbjwtOUxZ3SG|@s zInsg-4wl7xwzF(cQ6bxEXvsJ+%cs~a_QbJ^=*nn za>?arEGQ#wfCm9tXob%Ci~izu=ib~}Er?e9qAxt_Fum$AqBB4&z|OW}X`Zsm_mYa| z5-RVUu#I)@*?3L^!7*fC&vIpzeHBZsdzL5Z1_`g&x$ph*jo?!a#?SAuJwmqv-|zjl z!L_EXb*ZDkiv+BXt1e>12vtkq!l2oJx-K5(8fyvmEe8B{%tbXI35UhQoHi`uxHu_c<|5|`Yi`Q+v z_!pQYL&a^yOKzJG*3|F6+bgtq{TBE8m|;GaXoG#I>+l;?nVg`t2LB?oc-@wZ+21be z!Er&ex%3}!Bop*Pl)%jJ)ot?FzVxbMHzl`#&P}S+F=<+U>k*t`!Z;}yw*+j}QRLi# z2flsYp8So)4_B`OAEsqOjsH8kuKECZICkdn2ITX{DKUV-c2C>@(l+7i-N)ekYi67k z;r94?YgPMAsrKY=akpEgp|m)HGnv>r$f5?|%K^!#6CvPKGd6St?!$RpOPFqcnFwh=M;o_&5m`|jAL zG#6G#OGy@az@dikncmE7BMqHtX8SvL-y^fhDY$<`dy(pJgILBfhX*Y7w60qi7r4^7S+U|ZEWgUE%5v>cAh~ti^7VR!xb2py zH1b`x_NaNwReNo=Si-bEv9-7~@iOy>GBC2ksY2f6o9WfMgy}W!6=;(^oP3TMy}F)P zm$rNZqAaGvXX1%I*X_9xX~TW02_2njgwlkV-EjAmtV0 zOdh<4J12K{9@<^HGI3H=$!}01f2tzPCa+_cQ~sEpB=-f&t+a{JNh}T{dS3x<;#xO# zXnujuoAnHz|LmqSm$S${juiv-URqf+AG3opl>6T^))#qAkMVZ{!*;!9GJ+;)6~S~zk1udrY^b${;f zYRhc5$6cvfqT&v(8!v9G+a0`CL#d+1`#8SyZW8nDQeQMr0lKB|ehs0`z3Bbt0M9k& z0%76}EPAr%2}a^!W>|SNlf-`q#~mMkm2up0j&j-CgPc5rJ?nt{WR*YSL{m)*s;w3OT; zXa6_8d&Be!Fja%yy06Uk_k+nt!VDF*<%N|ECcn&k{9W;vys+1U($7&6_5!E;!z3NT z>0$FSwtQDyoEN5}uy~+-PoA17N@YC$oQx%qxMHE$Ld<#o$R$W4A;z4De+YN6&uBGW zB8){VHmuknHaE;VSb=*#-**d9zPWh$$j?WX%w;uR&$xquBhwMS-x$t{AP@ezI}l;# z(|1@Q7>!VOGR!D|-UJoNTz}*drN8w;!eWS>iMweo@e6M)#=@uT{p(lp8fBC*Xv$-B3kZz;$tQ|5iKyktQH2OJK^tCHZ5U$wH(;P5?-H zJ}QP}A8~oS;4i*cJm$HNJLTg^G!QI{nmZkZz-v)|+n%}M{LfF|E;p_A2oe_`F9@-^ z_!wHLAcV@}m>Gl788+wlCM^gC?!xpeB+x*KqW}Cf2SQ_58u!S_DIvHGwCv9Iq_1!0 zzAuO)`b5E?T~W+b`s5%!%|o0Ja7uhg2C(d=>b^^_e_p-rk2lC07jwx)5%>?jU9lLs zYhDcU(gjZgJ#K&tHaY%tw&bjwl6sUpPVO@9|Z zhhutAbz5qc#74XiB)uDOrbd86n24Lv8)xpQ{X`>uLJv98+Gl$WAFCqzM2b@<=2uU5 zC=C^mJ4IY!NS-hr^coFl;p&rbrtv7m{UH8muu$^qdPVF^ilByA=P*t(zBN&&j$OQu zVZrNc?GfRYaG^rpVLqrI^s9bnLuLF5a)p?L_AWDU;W;uJX8i4u=RITUHsNh^b_pea zBFcVZjMqnQi%QdmX>8UdT&Z$l#)?nYnME+0?Wq;Jd7mSOQVCPgVhVWNh>;2mHd^fA<#c?yZ=@p+nQ^6I1kQIqjjC01@ZOVUZ!9!GP}@O*bem znjfyo2BvP1zy-cDzIpt0JOKH5`O_KBdtZakjp+^@7Y2(u?^|@?SUGip%!Lihcj)9R zO91bp0!}##$`rQJKa>-Fqs0rS6ch_Ni`k6}+?sw%rIUoxv^dgLuS=S zZ@GK z7;9#0Id^_>)-(~o#CL(fbCL1~?3_BMM-EBy7~~tEZIf`f(_D7J>tBiqzOhVZ+DNgI z-=9JRuB0UUcH(P?cchUan7;x{PD^o6BLGHmqRxRP1xx?ZUjn&hOeP1jrigM;P z)=zF4dT$bNmBhJ6_^FKI<(SIU(KG_*2xB3Oig!zI3khT2p6#oMLmDu!S_#|ZDD0}sX@WaGkd{zcrWDj6W z&Fmn68th+gFkKONWrfsVQG5&h2#7txh8k=1fKORxC!rBCX9^9FNFkZmQb+I`3jwwT ztyF&8F13-+K>v`<=ic2;Z!t<#eX@GTNQJ8#^Ya>DB5`i zGv(82uL#5Jbipcfyw2{Mf~cwDTu=V&pFjNoHjf=RZSU#%Dd~qfzhDfW-60tNXBdGD zHPIw~z-Avo4&L~jVSLwan6?7Vzabbrur+o;+fr~9$Nj|llZ=6sMf!&@hx345#CIv@ zgRWWUaKQtA$TgY)Z%)2{oW=~#;ZBv$GYcG_`!M{LuaoC(*MKNUc)5j+(ABVRyE95v z6&Wj4B?|?@A0#eWhZu=J8DW2`zNA{jQ`wqDETk3bN3HiSiXJFHqpMz%ZxnT1Gin;bM2>% zzu(`kb1D6?X|St-;XSpiO)i=S|56?H_&zL`Fl?hms;-DFXR`BaS>CG$lD(^x^X>lI z&>HP|nI5&>QO?Nv!^gQ^4`4eptMxuryD?1I(*1q1?&|d~dv5B5Y}YuIbSeq#oG_Ca zu<3ZtchPe2IN$#{b1=W}28l?j*B>N-n4L5h&nk1YIO=%J`iptSvHx0unjJU8hIomG zkyW=wmB(@oId{XJJ2hLA%yd#RjUD3~H8RkxStlN4s&5N5)?zn_#s1kE8oee|5tL+uJZwa|S zra~g*UJftKpNf5Od!ZSR=-1ESn2B)55?R62NfAFLm8THFr3q<`Q#qHMIRo^up=z#- z5@GtzKs$5bubc0X0Dlxn5DS<8DGCkO@$jp@D z05E2o2dxcSTf`(!EGxaPYTH#t%gSSSF!uLssMw$pxV&Zfq}0XO7|DRf>znQNR4hGl zX1QCqwXy=NRZiYp%ixfBqVkH&PTq)xKZwkesv0y-_J>ncGGnOYchb07)ZQ~KY-i5% zXFX_VmDl(i=Ugb~_v{PtFDjKY)k{1%w;96)*{-aCmXS+Y_fE=ID2sNjSyUe|QQ*`S zD@1*wBHDPX=EkgXsIi>;wj?uDthC|R9-!P3$*V9DAq=?jh6zKBS&5rR*XTsN7+do; zKcMRtaUxv2a3Z_hroc0W#2qa~bzWCjmwTE#k~mFInEEU(r)*}aZ1(ox*!Q6?ye>1l z>5-LA=ZmBAoa)zhTU}mjPxr4xcRw@8`8E$;&1JdIx=hKCfyT{}7oVI2L0svm+CnRx zh`?+Qm8#0+2jd<5)6hM%d5K(IBKIqC_&slgoiOpR+Iz&JuqTu_73a)>x?{DfdR!U0 zkvR4IldT1<0(jO}3EaxGvkv&r7s_d(L`n1g;g}Cmo$&;wi$@X#{jA5@Vb_}7r zmN+fLEIHo)Ip>L+nF+7XLX-PMDNihm=9cGX*8QmJ(27S_t-qXvXVgI?(S1Yu;EG2J zOE;|3eXA_HPOfdsB7Flj!?%Zn9xT*fp>?h2@V*FXpH;PM_t`IZToEs=q34dO^9coO z4USq@YECZXM`CD=?khML-^l+(g1If_J|0vqS1r_#=?TBDa#>QQM|mbfJE{&Ow_dS#vW7j9ktH)AGVG_G|KSp zXH+&=0YP+Nbd7a{ixc+RZf4e~o%5sP!BECHvC&Y?@F=NUiwZdYo+wV}@PY`6J+7=0 z6uYrv>G3naqv!&3;wO%eGGiOhl?mE{wWetu-r-S!WkUDI%adQQW*E_Q-(RzKFWy$6!LE+KrH3}q zKA@;rA_eS?J?9TBY{WNV|3>#KHP|z;1UwU~*?(lkdiPb&_aB9m*YAVG@_`MFd()x) z9fpr~r|Y@@iZzt@y(qCg{>?|!Y|vIxV9nm14Qu9OEp_Hn4H-*p2}SP_*|RiR}pxR5u_5$XAxQeuAcDF~J6r)i!q3#L9BWhSh*BexwZ8)J|oU`!I#kXt3il^}oB z=avv%=q3UCQc|1!zpQ6uhYZCFQM)R|?P{_1oN7m2;*koq%{|@tBIBe(Y26J(Trtus zi&ucChD?&mOhmbFwm0Rn@q+lp8e-`g|K|_C(|T*{hdh%0apsrc8*b~-a2nUIR_~G; zSOdejju2L!XuHFvG&pyMM=A;#0x!a{Ys~@011zFjy*>jQy_=c_GgIThnft%Og%#FC ztC2Gm&IPbGA!EBO2D9OUfgm)$d})56f0g6uViI-qZhay1W%;wFv}{&2m1yq1&7t>b z-Nz@-I;SGY?<+OgyG0!29nO8QvT~v_{$!K8PAW2|yCs>;&g5g@C}vq3DHdOL&G>Y2 z7eIDF^fCImU~gmckjY-B%6eShx}C6#7Fv+oPAp1Ci%y*c(9x9(D&nX z2b5MeyU?{#{YU)K{w?x_;>@X7C2lvb;Q_f@1qR+_mbK>Q=}}^ir}eBEfEW9AmdZPO zeIrk4sVivhH#Um6_37hUbpaf9_!uZi$6$SEd6gm$i~{I|E7%iYb8|=)BV-HjglBoRY`5xzETv{S;P%V^i^k z7A)@Td3EPvAJm=e{j8x7@6%88qTcf!eB=Dys?jhy`qVk_g%%jLqC_SH$%!m-kXX!Q zos#BRr~Ivp5tGA6^ZOmy3)@_^W;Q4KHOY$*&QZ=fPLaRjY5jIsVos1N(38?Pab54_J8> zpab}rKb8AT4=kY_dX=3l+ii4KtO{imuY}vA@tU1|VOBXueskKwnCgwljb->v^(S!R zLj=1o7~~Iq)z=( zPZ!#syhhZgk5A%Odl(fC6UZgQef=6yX71ZkdX5^`KJgw{Rz3YDF;~n!Er0NdiT~H= znL}~y4?_}0OO~YN#>$gy!HC&S{!SLBN66N{$=aqXl`W~g)`7Xh> z?}$MmW+kh*TKR;>tu|9vc;tFoxpUQ>`Etm=6po>b?!Y5I@nwgDOg#C zfolb3yj~Qo79$9#7YSR|ZcKTo3(dIfT<=XWYx4_yKV$GV1|wP77r4RujHx*4rdTn) zj5a>45MO46+zbQ_2zsnww?-7!IPpVZ(i$YlSq;8M5vWS*EX=|yG0afC0O%hfQ>b5TJUv*{sQp+_j zP3Hu-Ig}Z^k1|$T(ULML4@=);n|Ge^LCwo#GfQX@rmj|Zpg7HOkNz!}BZDG?phl#( zL?c&#qTtTA$&_b3NAV_tQ5|G6Z!Kz#+P==r1Qr-^=r42iDL+PPA=Ba+g@fb$qz~7g z>B&3PmRY60Tunhq<*1CiWmdQy^&PCE-Fc?>!3r-cL;?klu!m3S-4eqH-Ash_YACOs zn_}z#QOF;xpn&=2)2GhKTQ-(i!E*4l!lNIai*~qL9qdepJP301HL?KXm=VqIXaT6LyzxLQxMZiDLs9aDVTnpc<>97v8CqlgL>Coj-V>4DJ2h(&$LK;QaNA;L>qO)eThqR}r$_;qml_g!7a=ua?egW@tZC zNH*J-a@BZ6d@hs2xY*5M+7s zF0-bCTCCW#SXE(Fx26IT4&NIRcpducC8t4M;9-$kP+ZsXd`#_vmM~%pTu4A9TW4(!Q{ z{&dAxsR_+vZ%7STi^~;D)0~R4piYMK&!SMwnn(e>drn<_1*ATN0#S`w5BFsyvS=X* zpC7zT)?cJ$*mGDX!e^|uyZKr-cj7R!>-fD_8!HeB1LTznqJf}$>NJl$?4HU&4vAi` zPeXf4`yR5!k<-#9JNZur$~kU zc|>w!W!zvPjgQ;n9B6+(dsuoP8S=L@G+`Mm{33#K3YFANE`6R1P;qGzh8NLG@Db#d zqIJ3_X24_vhP3WI$W))fyt0^33!(5H<(ECPKo|+PGBUmdXTlHOYzC0=aT*2_aLjie zNgD(ef*(F7cToPg)tmIov5U`~7huEl_qHB?6cj6Z#_%qdXher(`NwCf4JEJ)-h1_; z5-;P=yYv^i9W}2w{C1rjKLYB2kqA6OBA~edSGM*fEEo6y*ynTIgG|Y&ec*#Q3wCD! za!SywAP=2~fVMG)omb4g-dIk#lwW!$FSv!vcCDE!lUpipOrj4W@glov(6dv)VixNH z00qkBxM&88Lh^-&0JnnYu?*^Tm<%ClR+Ipau`>chkRtN&7!W)VDtHR;E&$wH`>;y| zm4Y{brSd-fB?+|ztW87nLch5P7Xi_i=?I((P^zVdZnBDO<3?vk8nW)okz4^_ z8XpbAcP97QA8@}iH^N}?ELw(}!{EBldY^UC!4)cc6|0oZP$H`6APCD0DvpZslh{$f zh#kbwHz*}b$kPgGn%w+>dAzQOY#x!l*C~urGQh~~dcbR|_A2MpZ;9abiC0KCH#QE( zn~=XqDAAt#PtbW=>$QjNj28}gl?&0^E`ek6+y3gp??AKuHcKNgBfXg$^7~V?yE1(T zKR>yj4b*S=7O$1)0#?;!QM=Q&iE4}~osZ|s&5$$IoCdu#NhPRixrU599}Q!bz!yzm zZJ&SH|6U1hDmaQ$MDH!kRW}IO#L58inUp!DaHvWOl}4d zHi`Q!ed8u4T4N#b~$g1b|R5+F2@B%l|ehnlL5J zZ(yr)q1U_9Et9vUBE=rPe0x;D@gv?JXWTKa-|53`UQd{-RmJ;r$}%a%03ZNIpp6Ii zA)B?wPOG{xO6kFdmthW{>|-X=Wik0vDb>jfu_=AFgl2JrS$VPDydG=tpL?l;XX_>K z#dlx5gYn~PIRI$d;8e|SgE*r&BYd{W`e?_p~#!`3pUKQP=t zGVN0)VM5*Fa9nnYjOCgSuJVz8oKgsXrq@p)4|5dV@;$rqh&~7FlA|&%Se7F+f5Lat z!Ni;Su->LCo-o`ki)kuerjIq-7xtb>uky!ki~OE~ zvC8d(5n3Cv;%$&zci$^{S^^>OtxN0*JbgH=aFQ zZ)vpqWwfuhYvR3};fXLiPTeb14QBx`W8#yC==EO3*fHC6O>$#>wLPf{q0j*$v&E`8 zwK7fyrgpv~a;k1)jqzNbPg}W3gX=Zp&Q;gMu8I9B@8ri`kkuYsP1uz35YT0O*|~Fg zMLTH@U%qE)5sjlhSF39dQU&zWh3rbkT?za70OFzm76F*M^Q-{`%`4$8H`CuOhMcGX z1MO721fl*@3XZ20(zJ(@?;-vH!;;pb^ruxIfxw`O1^_f@kw2~g=kk#ohx4hTRjf~+|B z%U*5`GfuvcbJ>Vkd;umsVI6voQj~6f!b)D5l5xVyK@Vn^5==8SgOl;8Dgh|YPHZ^` zI^*C%K`;jbT0;TO;7krVHZUf!`cuAUMLlP_CF_Rmn5PA6-Q5J;H4Eqcyy@nFKUOMz z4-W3U@XYJ9-mT;VEvNSGswz30JiTZ|-T_OwCGz7XVX`~7lmka|8gkR0SP`Z>}vVqba6D665y|*#OR`E{uGS}DGM@(WFLq$ z@h2PG7W%h7ZS#v3gljpJs_sMIx?86{ zmr3mvB6p>5TC1nirFdz)OcP!R;WYarZ&dwlu4kJ*w}r~6ve(`uZ^cUs!rkgm7`1PA ziB>a;ldBT74}AqQ?VW=9o)tgM0CY%5J8YHCysB^_tO2d?TKi`_=UzpY&@XX$7@Bj$ zGAT;T3iSX>%@roVNa4%NxYM*cjU#L%V!WxtC%_S@K#{W@HwAgBoDHHHOCzB(D$c2AmwR zVsy=$JSzJ)26;@u#Le5|(-OiEK%$MKYu*|WCeKxmG%9gZ)z2fgeOpTBLn(H4iZ{#1 zIXmCCytnF5j73)5V6(foM|m;ro?@C)PPXr-&Myk$Bsd|rvwd(GoM6+O(*_gM^qn)# zO3m?`T%hvy?H*%tyqo$Ljt?>L^X{4?EFJd}D=Zgx&dY~fgk{+_=k$&gHz{HnY$}dN8O+OegA6)~ zlbmw%a|fD;6S?*|V^1vHG5yu(8u~Onfc~nPT~03ze+A5aGj}w^hTOTpgjq?P(h|jW zMf>bEBQlZlM+Oy$|Cdks>{91!zv1YxJXM=QFDMELcv5b*@4L<~hw!54#fn1Jwz;5f zr0-GKZq;U9Wtz{QpC}HBc7=}j);3i%*s;G5hPJb~@g}ir->j3ldoq9Ys|ClhE3mW> z)D$#L&1p+TyX?V|Qief~vZzlud^#uF-n+wsdiLH)zTyqj!12{RsGjjth8lMplT!1t zb9>#pbHkqA`~PnEc8gFuEu8||6DVe)@sW@1eTSxY1IohGN>!pUN;FSz#sbA?eN;|1 zEjhTN-7(&WN%Z^h%7)YPw93k!LKyxS;aBmgnMX-eZ}H#5$H+x)7?Sk7Fy>dtT|#x7 z#gzb41_Qce5;`-8Z0X}S-t8(q-jA{72#S90=XF!Zx049WiRU$5A~@58&HcWP4%c2-PyTNi<;BpY)LBf z^{3{k2BRsj3tIa{wf48?Xy)@0W{{`yRmqOw-6ERh#Y8Rs7BZ9i`a`I zOjoT7*ai?gVUd7?rNEE3E-3{+P2vUa# zBmp?uMt%4AjhX9_3i{R#4D#Z#9D&3PQ{x&yUw|Ky?>IU-B7LfP#vzA$=0)k3&n@`0 z_{_GuPe4093upN%a?JREGNWarV7N+`FBRgem|f~ncn~BhH@YQBAbe@`IVw7f#`)^_ z_%D_}n8m>E)mmjBu)$w&jw}N%MXghy-K5M2Nib*(k`m0KC)Z#E`5Wpk5uJNZqN6;mAeI#c}i2tf0VSNKws^?R@1-(Pd%{`$Q*%17`~ zT0;gI24MC<0^@n!4%C*Xz(SYZSiFT#zH96(el2sp66IkS@2 zcz4a%ph6jB7ou*MEf3yw7Mg+aj<8PHtRNs9IAww28eRvaOGu=N2?vmRdydE;{M0#p zkRjk&ZGrw=x>5SfwYyt!#Wt3RybFRJER`8M_2~?tX5WdarT`X|lTtWtL>y|ZBw4yJ z-;r#a3!Nm_w@h}_bE?R!u)=XF*T@i!MT~%9i2$}exuu^vELSQN@ht4Nby{Ih`?!ad zvmZBt(?w>Qo0%BIV-$@9Ls6>`g|175saanaUNIj&3@Qsskp{fX>I`qbA%=2Y5r zf=J<{V-wEBxo_hV6!u#0g*iS@V;0DWpE(fW&_57*`qnaFP}L6e8=x=;@%!M zZrhTwLru@s)rFB6Chq*nXS&W;vS2Kslo8O%Ben0Inad1VK48TL4n%v(8ud?tq#tRf z^-^4|3b`iaQWjUA&~|Q+<4f-zQ1a8mwZ$j%!LkUrdsZjAh0~sO3PX72Hidqrh~(vf zRnCMFuZJ-e=Gt$j|VJhizHqnRnD$dCU zbsWh6W)ng}&%7k*Q{CjAH>xc*kwxZN5Bl*!{5IDUa|Y^48QzR?XRDOcH*$w-<vOTn6 zMi1!}Fr8pOnM7sPbM$gJPkb{m9PX7F!lK{C4F{m8PSA3@8owwk+dDilAfjnx4BrSa zL|VQ?{lga)xgpo3(r@T$bWq)r#L4Ht9VB#B^4LZggQ%mG7!CaViqA~1 z(Q%=cX>oE8UpP|(>um1Gl7!AT4$dl38C&|@F}4+(Cwies;c%vX&hW?*4M49|zXS4p z8QncR5igX^*Gck`*4V^=P=cJekpMvM)hh2`NvbWmb|0`4I#oGBxVob@PlP|gF=`;c ziHKBV6T}0a|CVY$*+b;~EX8?BXjOWf5#yu|@9f1(Lao5E}Bb!<|_p=;3PWZ?r}`KQN0T}AymBaghhc1E@ z&R^qNS|41mZFzi~JP43LJBv~WPX|AFR#OI|0u*^%Gp3jUrcXBOPal2kVdVpGPzyo) z4Cph^KpufKK`;$ywh&R)zk zfUnAanG99|??E~Kqsc4Z3U=!pdQ#kVsEEPOJXN<%yF`Mh{ zatB5R50wV$OM-E!w^t3WyRAF1AC{M(vfcl3M`ZA=?J&%M_~`nnCo7Du|9-yc$ehmz zIP{`1=w&pBV>D#&4ZNfu8=@}_%$?qCwg#}&j|~=b#1{(iO^N>IOJ8OMG5Edymi_y` zF2|1G!X#)3pLUl14n*OFaXCmSdqEIX_5K{_(a|j9K%@;3t=%1oUT8+g{DZ<-AW@r9 zLZ{0(oD0EBB`^^h|MCwXZ(u_z2Bwd`G&T4k;Ogi(akYsaGvC_y=eIYE z=2$^k9_QPs+yUt!`UZ-Zbi&om?V)Pr$@tK6`pM=;RgbD}XzcF${`l1cWE={s`TC)+ z!eX5ACO=r@4+W;>a@)k?ooM$H9&he@_QMF?|7@(=?8mX(IXPczf6Yl7JK8AClX+WdWuqu)Cj};W zeC*xOIIJm|Kb}fKj98m?090DBU+yfS&9T!TN**pp2_&%+}Sl0TV zc?|SDVmxZ1v#)`68q8bs$0n7$N9%+Vx&}r38UT1(M~HSkwg~8BYgSrQ$9@yBV`t(j zBE;3M$H?F^x}z##G7{tB8+`^WxHYeuIp0ecxP`Y?iTGELTzO2Qa%na%M~Q7b z$bHXxe@%V=+uo{WN`6yfCd|gPfLcvSFe}A1VGD7aO93_mPTMvww=J(X*rfSY2K>If z((>YH;k=hE_2OjN`WU5_BPQY^y$A-G>X57ki+XN9rC8y zEVK?utsmr-E2#hzb#T#{tKF&{7k)kdD{vw(GhM7u1gKO&hJm!m$jsGc_^n6v$WSE< zAPgYLdmYaqgP3jX+K560>Au4F`yxk|gjo}J5BI>xI*ThV zuZ^ISdo0g`IW)#;gA&p~D`ZFD4yfI)%2hX9JVDN2U#hlyX6xkg8++BR1f7gqkE<(Z zm{w%g06$DU%D3so!6GKD;YR{{-zH5-{=$dMjyEuqTxgtF3l&5<5nyY3s&?(7cz`2| zP}>z8*@r|!vj(`>mcT^ReOnLa)UY>2R730s8*AK*TH~ZZCB`?uF118KXa@9wE%Pkq zdyskK6~JYUd;EZRVd%?GH$#6mym+T|%bUZOp))Vyckd^!9>7uT^vD|E!w+F01NuJ% zPyM z*)Iyd9iY#}(4O_1iiKzP*O)_qlAA$vD=NZ+VsGtGxf~0rKhDfok-57T&TNEP_h!S~ z0t@P0{z&((@No@DG|mAhAPzz{#Im!7#5eX_ZlJu_=POKVjPW?f=&fso0I2Is%s`OAtze5E$r1CXJynMOOx@W+af zL9+$`;{AV$*BZk006mOH%uVRxC>XZ z!pB~m4=C+SZ&j64Otv;480{T7)M*9FCj_LvN1EYltdkuGq>NS&$(4ZGcQc5bv`(h< z|Lmh}@C@Kx`=9U-jHBAY{5GYNdz(bm5~NlzqH&xKBf>bZ z$OzA7Xi_sfboOwD^RwTK9U<^Uc?5IpMyRUibLT)wyG6-xuMILrwosJkY4)06u%U zoGPRjCx#j53dZB93H8;!XNx1PXuOE?pnJpS?yr&UDbbCvFnV{e@$Svrc4BD{jhGCo z>2j!)#$s7gXq`Y>A;Oy36k2cHjy6QT-%+ZpQT^vZ=~#Q_4@Uc8p|B!yRe<7o%86$X zpVPCol3x>j1Z~m0b)-(%*NjYaqW25mz-9#6F?k4w#%TLj(Ad#t9B6GwF}>z%(K043 z^gr_A;b*J|<%g`Bp2`O8ZyI+L9%EWYHQZJ-QVBeS+Lm5_q%pjMQpb@6qopLb>(fNxWu&%!eeWEi%WyW z53HlRKRH~vty6XM3y+A9J+B^oYuG(r>gyH$eBGT(-Qk}f8JVZnzV!3y+|c*ZZ=xNz^fB9Vq{XbpUfDn-%Zmo{jVGTr7TRR+8M*bLjoa`-B2cPp?<0$E=$oy}Ce7d08syp z%OTaoG5?g;zS$o_bRZaoZs`BuRR}E1$$t)VI3LF|G+M3m5=+(L;?LcSuNateHSzLL zTh2LwVm+-U!ym5E|AB~QIKyR)Xsr=*zjiuvgH`WT_-b~fAGm>;{%%_cfvqZ6{~_oP zjs&zqAIG~w?SsSruvVyPy=USGU2}r?Meu0a<45Rb;+dI103sNh6vy zM}0Z@t=TWzt;?VOnH}0(FD2|^m z>f}WANCXPs7R6FQADhl-Ee-qdwxrM;e-FQOA4n1Yy3@xICsHjV*4Rs&tm%c4x3sN@ z?^r&il5$Eb?O>NR$ZcC_)R;`r8EmUaGMw&HO@FpE)VPkemFrPD`G#p8A}Msw5pV7n zp5*T35z{9vCnWvd__9eu=2lIx4Awv*;$u#fjI?!`Nkn@4s9Ut$j(I8}_?>6^JNUx~Leop2 zU2+CC_ZRGqxL}=)*Rnu<0`QnEbZ^7N4NHOewO2pD}Q&~>oLBk zlj*io-mMSl%RRa|3b)oomZPMTYda>iY8l>as0v_i%Qrsi_~d$w8OysV`1j!7$B%Gq zr;ccTG`R6D&)oT`SxZO5s!Tn`vb{E6 z4olvEvfM55B<=@w5(M063xBfsXk7kI(Tc-04_t<2%}BzURbvNNvpM8{Yeg+bThb7ETDwhfwQ5ubeu7kZ*h_E*OJ zTNOBSxJ|rj&Y&PMK!**%OL|;u*$23LaW&0Y1DjF9@9p3GQ1UkK04|{Bbq6uPw*ePY z&~2HN7za5b-tT$?Nnr&N5%NB{=&3``DB+<>KD1}mFvcB08THAxop+#V(bbwi4u$V^ z-BZl6+_#}RJ=A)J-@p?+zE2kp1Z~u{Aqz1BH&QH0rSF$p2*$H=Cd*6$Y<~CDiCB9S z%QHMxAkPr3g^Y{Sm-l06b-5-?4!lLtax^ax(<(-sj3elvbGuGAUhMyCk?BEAx`QCi zX1~UhyuD4q@63-vIGjAAB2!jBrN~i~S09od(s(kI$l$DaCmG8|L@N)0kTxP(C6oqm ze4Ui?0SKi-;W-`)wJ(GKH=5`;MnsSt6#9lY&+Lggq=I=BE0$rQ>nSi|tYsPC$4AGV zQe<@6UbN!$f}(luF=pH1YF8A_yX3Qk2nL1%>LAj12(pV_;}Z)aKoyZRMTAL(HN=aO5mbmbP4B zITOQ(ibM;^92(7tL1)&`jkjmN;!M&^T(4g2kQ_pB z@lqjn3ku_+c&}U5zQ=YtR$#2}SKVY0Io2xwoHN?3suv{c@5Gm!Xj9f($ZvOU(DK*X zXsrIRn&B~}BSe=Wf--7i-fWjVi?HC^)0d<5=(wV_JyTva zIMq8hlaa2gYT@wsk;k40t(Yoq>FWxWyry*eLk^0nyGHLCIP?TUL{d~Ej;-R2#k=O) zM95zVfT4IsRdPMLCmt?oQS{TVUS84~*4P+59>q*HRK!sq!1&VHPL=0nb}9s;63e>I zZ068XkM6lDNv6onR4>QL8uVs-z!ZPt`8PPo#6V{B$0g=hK>=oY7xNVzXd-quEZx4F zjP4s&bc|39b=WPshN`+y{_FnEBo1&rmc-~P2e|y#(ZSLVx?JDggp3`L@he{696mx< z^sLj?4qrWL){SQ*Eg2Ma97I|Zafn4P`=5ix?P{`@3xh$WqMp;S0Y$IzvbMwVTCjFi z=h?Y|aUaxZueMFFjfIl6c0|O=T1NZ|V#f~U!(PUqa}`>)OZ!X(KEZvG% z#p%>qMh56;xY87AW;wAaOXkC>e}?UDy9TO15l4pzrh{vckeqYW)cL8a|4~yeR(&;B zWb8_KS>MAS`8(qWqPV~Kiht(@0vVtPG>JW~UO}eo$oRXRD4yz7(9>`bO+X5D*=Lv9 ztkJvxIJmkGTV-C|2LT+>{vZTvLElz~_QfmHnths`sBb|b-iBh`;Ge@0qKLR3_9$F4 zARZhw2bZ;D>7b}OU2u2MC4o!H56(DP*O;9y{-+tn1kF#byRSx(!S{jw3z5N}-TG?b z`D50XV{veA2Td$-fFBoQ!)C1=U>Jhr%aN479kVq|qie6AU2b}ms@4ZEM{Ne>?_x7r z!ketcV|R+L)W0I0X;5mv({H+Q*>BJDA}@6KSL3pYr+ZQXyHX@P4)JF2VOg}ExNsMe zkA?ONllD73zgI~Dh_7;=A6)HlIPO}6w+N7maT!c)a8|TA*h`>LDH?@QT{y?`S6FMb<*_M&>>rtt-Le*0lc2+U%2(CNDdwxzSFFlp zs6wN~Fx)jxJvNNALqGxo(^AC2s*ZI5BMrLL(P64059+Ozu<`D>Ol8{OmSBh#hyw!)Gn7AM}rpsfUv1#V7!-mRkX1|q^Cm8gute3u@ zjIP&JrZD?IN&;lh2P3N_kt)NeSO@?GVSI@Qzy3CM?kFVScyAIw9ydc~S37k&LnVlu zuAu%*gu^ra5Uc7)P>idTf{D$Ba=z+`v$AutR25p*?>$v#7!7gvQirpd(>c*ohRQw6 zWZme=CZ$3(#0;CXD*MO|C~Xf`wo|9LF$4c4GVy#fmcRWN*u-AnkzhOw=piD>Q28NL zOr1K1hZrm~7aM!`Bdvmw9X{3Z%&KfJ=(1SpjPYl6H{p1+Kq!!)nxu}`4Jv{;qX49; zoRu}y_Jf9its>G56{CY6Q#iXtV1JNbHJ@iKwr(=l;TiQM?h6QtoN!10zbptJbPmS| zH0=@Q)|8F4@l!myKSCBIPgUa-mO-o$V_9NP0URyUL$tQ>m(dfylAlU8F|O5mp155B z9~v?4JB=Mo6|uX?W`-88sY6j&SpzS3gc6eRUB=3d@$0z-6*rnhp4EPR1zj5^4hAlz z)w}`KO2}g0vhiKJgNJ<=+5~4biS~VFL)6=-1 z!r>ThI`n5X3NWrRaWinmOK4f*SDpF_EYW*-g6ujM!>mnoZ;KnWgjOp}f;_!6V{oi@ z4kqV-YOs*+mT`OX<$*DeVmRZDUJ{@c@xcZ4fFgFd4Z*Jw^wfH5%JMhXEE{U?IjciB zYnBa>B}|@?y1#q0i%3Z~WwnG2f8b@bfbCMU8&$DQP}1ZHjd~E;R|riF4GV8W+@6Gd z+Jt}=5iD4TXL>Xg!jHy?A(|@`Pl#yxA#NAM$x!TZz2JYs$Mh(VQl!a*e}(k70$P$N z&;E3yQ3xDvfR%8}(jrMAEvJ8T|Ew^kM0itls%dAT<1XHD$QJF_!e4;8V4$=tsk%I1 znaz9EW4^A$@dC}VFY#!~eBN=N1tFFBGw|cBRI`iaKMtC8hmL`*Po|eJPU7K;5R#I1q+;U@z}qpF7ILpK)Ktr1^t(N+;;F* zyaQbxEdci99S?G|EHTv=Ctn_L*cED=jUPl10HVi@N?v&@*MNfqk1!8S&P8y8m|C z{(OJ=#;mq~&0G7U-6GS2zj;^3{rGgt`{n;Scwo`uf9?MMe|H~YwToB@1zX`-;mN-z zdi}j#Ap4}X`5`l|AwnIhGg>B|6`zm@${x1ZBC>1IB(})8 zO%Ae~tyR;G8C}D=(Q8>N?l3>mEX9{s3`V`5;u=iv&|{9!RZ)h_K|9wLtlu z0M%3KSfHws6Q1a-sJ4(!sHAf}fO)6JFYwCN>kt|rd5Ccnwy22~ufL9<307V3=aU5q#rfF`;&nQElwh+$;k#G63d%B6zob!Dhd z-L~VGVyTngIFF<=rxy`QH+tCF-ro~{ro8?kfrJ2@6BcA)a%F|32NA`(2aAa0fQ@I(J-XLLnC^mYvo&wK@j(j;Y?PJ}0*7V22A0Nn3F(#ghV(wVBz0ED@6B@97cwI?h6H%a9rpHB^wmlxFQ0ujkg$0+;f9{XqyW_s{rM zt7Q&0$?_oZq}OxMC)N4@Q8`zWdx^+Ek%g=Yv8Cdv%MYI)^tCJ^56w66MHla(q!Fc4 zUZ)#h!2+rJZ(O{G;HOI^cI*a8BQ8fdF-&UZ#K5u@#ao>{$n;n~HDA{^J1cyJjDc(M zb{TS~MvxGnfSh=0fpZLvpyY99779k&%XO|W+CIN}IpT~3i2X*5mGhqpGaNve3P@`k zO}!>V1jJpZwE~D`5(H7bo2K>A#>7WS>IE8Dr@>1z;+L0kR9&r^429a&+>v%^=APi@ z&;z?cYd(CY#NbCf`c$uPS z#7MU_e7nCVXY<6GqZ|s6-J2iba)I9~%8e&7_{2e!O9=s6y8v)o=&<)ty>aI8$8K6F zU)D&gj!>sx=&Hu8=7<+XO1oP}KUlR)rWD&mwp3+CRHX?f9%OXz1miB~k-mj?afk*@ z?8(C|G;z4XLn88B9>H!u&xvZRFO>%d^gg68*fAcaS&f?+W-JfK+wjWHZbV&&dfh$r z@MP~HBmxC)IuXhFZp$MY>KGf`Lwj2u4)m2g$ZhQ0qLSz0d2ZxQw{8D8J-R9Bh@tHS z%;7gYBs~w~JtVL5w(z0>>>zbfXFP~Sp2nZy3~X%%PkP8dy4jCus_4lH?t2K^9~Rb( z>iWo`C4*a#G-X4Zg02aIfR{Y%gBt5#A|#~rde}XGFF+i|Oh-?tn{V^@BLkas| z=1ea4K%e0YW-_vxAX^OuNJdcRLgDxJxY%(vGaBkDg2&D*=L_q6m&3XC&C`!!Y|XP0 z9DCX+MA1!$@1VXm7g`>5X(3Ky_p;s4m+&8gKeX&=vxj9FWSXVf+Ctl<4}pvo?FNeSV(<%Gzd0nOR)~i_aWF_LY$WT5 zjSGX3ATB4)Ks&?s8z40ps?dfUvAGAEeQ5Cji`f8qZXWNr$oMJR?t`>#Nmg9#&Yl%P z3rYZsYLXF}`0!d&z9VrVT#ARW!g+ZA@7;=biE3{-^((A>&FuXx@83+W9@gb$)9iTh zA#etZKoPVZB;e^GjDc~%$8;v$`RhH+Rv>Kr5knA*7>8m89D4H98Tty^T*fFoL`~^2;UO##JLgdEs#7(eSe^w zoc=0n$q4OGIIo!%<#l_l{pYGaYLY3Xi37`5b(~GdvLW|{FQ;}T}cJd(fheYXf)sQTsV`3;gK>n~sHr6UF zT{RWQ9Ezn}D^DkqlXVPRtlgvX`*N2<%q~`D?wXQ=~N?i z@QPq0e$|vvHL{8fSf9AxC|k4HfOlG}{R-D}&qS)Ys%Dt#ik+)=q&OjD(Y(tM5VqE) z8E#!<7YDHFdd%WsCuGG&)RL^Mn{h^UdHN$Oy!AIO1{ml(I!%wNSgM++2}>MQOf>e{ zB_QP=w(72zJKqDaejH&Rn39UXA`hGVk*0gZ54WhqoQNA-W!Dm9j)!0uREfZFLbUz( zJcp_1wyB;3I=2BMNaYW7uzejypDL5Yjfwl5VJQ-Jj-V)I=0bPhXj<(BHfWykW&b^G zhhANVPyMU?$qBKF}Yq1I@&hPW+z(Y0YH7qKidsp zvPt-ONID zG)9jJ7;GZp!H)`TTK=-nX*JrrT>BSXt@)R>euv*LJP!s39@f9(UCn*-9gxZ9ZMV+F zd|23ZDc;F}HQWa4ucAu39``(i|3d4pu*oNEi4wPW!v87sAP2e+aQ_%!e!j37OdZkc zM<`{oZSOX;lgrw|@&r{qFu;23O;Z3vd4Ll(G%||d0W$fUSvEO*cBxsadKg-bQ4F9D zwOuK>7iX60Q@P`6lLj(F;UfAD$X_BJ0iU{hiC)gf!{W79``|nzyck064V&thBxY%4 z>-t{Kr-6L~aaz68X}Nk`P-<4ye41B}<@OYPa#0T)9kHtzz+G5XMTWO2>I`4I&x=69 zgkXV@;~(}%ksFz2^Q!#n<&}7Jgb`DX=Fl#suh+75?Zluui+Sj}5#YF)M6$ZV%Wg<7 zF0a654QQCwEJ6V&yZ#Cq2wgy=i>Nu&Z3i8o-r)>|?gAoS>?L;V;+E8nmRnDpdpQRz zGl;}m$y#}46_JKh;v$GOPMjm`7Psnecvgd%EjUNAw=q3$3oR5D*{~`=i!nb}!d0U- zcRNTbEAH_7@sv{O>okMtsRtPm?K^A!g|4_x?i^}#X+UTvZucU%kg*3QeF8oJjwl;$ zRb{M7?GA_@7D#oiD`iaS9_n;`z!szyVC$&&TLi;`@EeWH&gD&uewfjn#L4cZBb|00 zvR}FUS+AX;_TgRWw9zUGZnD~>KPUDIraX+zBsHy`ViZ?4cWwIhS!Ptx3 z!Lt4a3!9N%UO>dSW5TP^nmVwL0yQaroDEZ3M%NPMD6^*j*Y3#MzERzVimS+I3D-~j z5k^R?q)P|z{MnzZp>#(l zPbE!wXzJqz##d}DoQDA)KplWT(L*wNV3bspRH__s){6mdvKAWnqz97xRdSi#T%52al7dTH~sc!6QaRwkb+2%P@uU7mAc=YI@J{LKSjEvi3| zH81J^=>KK?A-9!b|MLEL`ri$lRxn!w6iVgrxfh$d1=Ugpzdo&H(%+(VGQDN2EHvT+e{gJiva}(u zr2k%19>ZkRC%tJiH`rg&EL1cXPFhyuj6wY1waiwUUPzR+VO}g;o%7d#!E|2s68sd_l zdyba8odZx#hrcEZ!9S4;mloXQ@`SiY?Fyj#3~BIl6KgUZ-b)s(vplba9q8U&^x99; z8pTAtv#W7>ogIH`^bV0$_RQOWs?{@ZbAmec-u=4Ax|d8PU3Kdd^1^>`ZpfwuN|Gqk z|BA8wCd=8O2NiGj0P%8C$+*3E`d|K0-*atJoAQeLZ{SYg_X>0UQD($Q-oe2=MA51# z+!%3Bhq=K99%1R-trI2zatLwToJJqC4!yq!QgXiQlf(A+i5B(!luX8_lk)dI*{mZm zx(@}^VsJqWEg6^a_t1A2oklt8uIuH{Sur@>Jm{$YS!mBSEYz~lk?spn@>Qoz6^F~! zX#*}n9=fMT@3qGHfu9R<> zo#q5K^%gbwZ|Opd0-_)&`NMJC$m7agy2 zsXv;a7e7c3)rlf>IB0s5eG_FdnzQg}Di+nI=AvRhQc9477K6yx9VFAYbF`i$xUA`d z=z?fQ%;CG?r7uX-yWWghl8y?Qg3>i zuu_e@R-ly8z>BVli0TsujF05lTCn^QMJ8m{qI_c&_LSGs_fS5f8{KSnbmh^N8GH5? zCh18!$~T8!q$S1HR&MXvIQ%SA`YCiFf;MDon4n5|_*vR2k(O2VRpSl=) zVWt~h#&R>w4Vs1H(>~gtoh3y@9Q&?|`4I^v0yJvbB93b2K~8 zLQyhj<>TGoQZCO~`N4)cMjzV4oX}+$XF|NOelU)u*S!wE81j01Vc=dk#wt74F(*Bv zWrkB;oQ~jtsBE{9DZ{Bv_NR>su9h!}?r5JstQu)f^B8Q1RAvj_H&Q2!D+~6VJ)N`+ zbsg?M$i9PAa5eCL5a>yG&o%=D@|+^jPCJ}56z8ivrzuOn@@lK*2usZr4jl0 z0GUNu)zX%6_~E&#^Qy`e_}e;5b(VG)w?90cLhJ-POLwuSTY7gqEgAR0 zCi$CI)uBPK@SX0oY(t}yax9UIPmdlnCL zE9a5}-nYX)STB0K;Y$*Q2U+g9OBH#T?Vr$=l4@bck?b&T)Gmm9+8rQOVjL8Rkr*9@lQvy6zUrTvwi zl}qR$ie9(-$;;f0D_koJT+W_O4!l46IGq$YGwk8gtBz&vogWUG>Q)>M-za?fw7}IM z{$ZkLZii^irXq*<)Q(^5(I7~ShGdRMJI%R~pZe}uFY}%CM_l%jZK(I1dX&}3lh(kC zt3%Z26*2apAqdMblH|)VSN>ZH#PX_@RUS2-i$rsQ(;W4zp_x831vG&?{?hr`0VKNc za>g;iRY*-aXbJ=7^tl?vi<&96 z^wne}aJ>S(8cL5-qI;8UWuH(b4W$G97SbEk@vpgg{(jQ8D_>=!J`oX*Jn-}@^I;>$_g5x$tvtYmL0Z2KQjJ;&&Da=yzGR~>g_RG_#U7r5l_Av9s6&(g+6L80JZpHvQ~ zSgZ25NaIy&-r3bM3^*GgA@bS`F(t{#>*(T9efciY5y1iITCUf>$z zv2yHhN7KCPRs~D2hA+I@v!255dO($~i#D~D>DuNAl;!NkW=1ucUGz>m*j<$CFR@-< zbKALBh`$J601(07ShSUqZA{sBoKBixGOA^Cd24TxFCeOrYQILvwlGyz)5}|j%{;1B zsh%fD+%mqz(8{Ie*z%)l)CSP)N49r?Yd%WC2M2Y)&=JmEe3*F9blB-!uqHjsct)Tx z+fgp_&3Gq$@>I)&nFT{Ks60iWL!|9?PsF#5j<-zxgEQ(d@vrEQG9@8bD?IAE;4XN* zMY#rk1`p?$4bQ&-tE-H+kX$Vy`?nk%$rp0BArBBK-hr0$v#PfdpDVi4=+PXI73>Q~YUOcu;k=uhEgw zo*Qp*OA4NidB>`nu^Z>x)E`kv(jX;zb zRuW>Y!^7B-5_08f-WieBO~HMSG@oze_wQ*L%HT2-O|5Hd49Ta2Xa_Z*B#NQ)skmIai>=f~&g#?XxW)*N-yK?34WRE0q0iwo50b4_V+0iaKc zFOn5pAnAt}0B$6ewlC)+07>9TEmebrn&{>FGS{;Q;ejLs3H=5ECjmxMns%RFS%3>) zHlc)3T~k*bq`Sp_NB|oM0EvcGup63*dJB*eJThliAv7p5^~W^r1dx+Jk}(e{M3bP0 z4q8YHt)ev$t<{DFu=-MYbUCD*2W<|MX}#*2A3X2~bz)IpdTi;jw4AQH;iocgz{`|3 z%E>q3r{;Cl1tRTUXDNXpFOf4JR0niUJz8>+7uKK%dTKhwZK7LYXqF zut_fSyo#fEGpV{<6E#S^9(b^GS(kpfnU2Y-nfcXryph@5)T(NTURO3$=ggQokeO2M zL|KQl!6Yb9M_X02LFs=Q8SCjXn(FrGPx4pHNq$D;aMg^u6slAPj8v;CL&L(_M?EU5 z1X5Gm$;s%$B;x4+HR-<}f&~H7C81#|=6C=wSk}?UMpiKosTH{K>jBF2vVMVluWkT? z-#EfjjaNLn@DiyP8xp0}yN{)*HTtv1(&^GFYM(?|KG(W*Xfp@6v4)x=C7G&=nR1Sx zsfw!Fv;kqf$ECxP)_!+oJ+%wt#UPk}dJ}%T3aT|qXTC_Qk+U<$##OHe$I}W{jTaBf zzS*!TD@kv|rlVw5vqC4$=yc+@iBhRbs%RPJ37+Rp^)lNPXX7&!hRXO=^sqyFS8vMd zh)L8Nlt#67q^X(>CtzyfC#F!Rpj|#OOacWTbe=g+f$!6sWF z=y3DsVUBz|;3nMQgUaoyQjV$sbssm|z%FE(ZD zR733HwXjg6_1UOXQ6pX)j8bF}2`59>mIdXzS7 zs+a+q1fl}z{9|F3E|2v3o1z!2E9zS#I%bv7{urDj0f4&4tjqH%xA)yZFRWnog{T;> zb!fFKE<*cie@v8*tz5O??4RM}SCk7eUmxB574Z=u6%|$8K9mj6LI_&omdRR)@g~5` z*~cD(C+oxKHFn%0(~liQ`Z{Rj%gs8w&RzY{=qsIFFhas(yjh*$bLXzAPpBX64LaMO zd^vy98CZ~opfH=GzE?ERCzCDsYtyyXx-<~*zZKBRS>iAD$MC8dDx}@?WY0RtRR~fT z(Sn3lvnKwcEvM?05cQHsk$rsX#Z(diq3vv+MR#)i|3o*#?O5X3n%zc zk8*!_C7a^Mn@?Y=7c5mv&I~P)sg5pmkjREnS`F@N4sndTY<$iknOVRVy3*Rl8Uh;C2 zpKkZf3{_6I{Pm{RNy*2S%z)EDNg0C)bwgo6m9@$9X^`oMz;-`Hz4@F0J z2VYdeDNz3vu%z)Kty(g=#B=@68y1m1h%9va3`X$L(>TLXp zo#FVH1+`709J89H{c}?3uDTf-HRNtRvfXf`Eyo~K^;u1cN*ZV$@TmLq!N@djq=d(x zY*l^{FxAc!Nv6hhm224$bq5^!2&$J^L=28Sd2`4A4O>!kVXHAx84y{XL>)bYqL}ej z_o{$*dMKi$i>B)3hSvy`t7ryg-Q#_Vr3nf{Lm~JLIqnJtx1=p6#cRMo7u-P!i^$=& zD1qXspf63;Cg?E@m(6XFY*F=2Ms(OkSAS+0^~y29wljHE2A9(kCZz?84jG2?0;E;~ z@fL`S6>gI$t4j!*8m-xlT-!`_%(j8~8%vfDSr;c5zh)&El-S$>m(c|r{!etW{V)?n zmV0QO8U6~(-$qqe6F&VkVY)^0v? zJX*V@rPqwvMr)CE+r9^i&M!FK>s0ME^}ViI?iOufoi5H%JzV~1MC;&IYgsPvkMY3K z10C(fy406+=@+_f&uVNtJ1wk%4#WWrhRv|mGGfv&!iIRHgB>;kYOCo+SnYiQBx4*dDAlb2Rzy8FX`F>*X8#D&Xg8d*_ zm}>lebz*<(*kEK%BWza4`dj4HOwkhNhk6g`SW^6wK}mrDqp4APBS6j=l(tODN&=W1 zp7e>cqNM$q8@R-bb^WZ*-*kLeLhurs>$Pdg5!qIzle+?32d=c-Z(hnjRBXk#&ja^H z8&@yzhOP4y@8qsv+y@H{tffMOHDp^jb!}%NqDr zg1W)3ks%vqpN0J7pge;*5E|XpK0sBL$`Yu9UBxLhW$n_^;pG9t!hk4lsLE7T7~3+P z&-oW;xvgrYp!Y3y7cQ5avL9QmX9Ewk<%iXJ@n?1HSdDI~ePdpomW&5y^`W|#Tkaou zUj3QHXdYMUV6IE;aF)-7pw}b59#I1)Dsnl+*7CnRwu^pm2e+K84|fGN>5@|^KN5); zGT@KhKLQ_D^%R_iOH2q)U_xYy&S8h#83#?oAOl{y*z3r^GzI7`{_ySDKAl?rgnwoh zBcyo7y^wJJC4LJWN&o0{NI13ItjV%79=ii(plBe|b{xfIHbll)t7mhaWl%+0r)b;{ zk(mk}PSs9_CIs6MNT5l{S6XGYNa|=fQZxlTLYGthHQs{mZZj!3*WZt}JUIAm!+tkA zT)2yCYXJVoe>%){@XZv?A)INkFC}>2BVTQ;1B7u+O3(gc?6XaH^b+ia zT`e!tT6q_VxxYEA0!}G0^8~r(`FR z0Dx#&_iY4mfZF`$E-(yXw@&07+n4uB#z zv8jc*5Ah6MsJ06sRoMOodA4}+hl6hc_rFMVR&^MH)s5zC~LEswL zgn=!YE5AeM8u(5@$Wf9cPCTn0-)Xt5>cqzDRX?pw`EbzuX@S#f6R?uwwygoS6@nTO z`!V@HV?Rokev^2;|m7y$lK2=G2 zkdfw}MYh0f9>Y{J!QSLUKfT>FyoaqDp%SS0Wqqqt!oIALzw5SEe3tpf6^xH(%^CKfu9RC0w?hI+FbJ(b? ztl~UlB!KxnB16ohxUq7}T_~Z6w{Y4RH6l>Dm$eIIwgF*HX_3ad{LZ7T@+E?bl;xci z-L~JEL!UaU(w+B{=6M8jC|&-~ny~K4vexrqO2bGGjlZcd&XDPZ<{RF0n?>X}jLm zP|MKIV0pW5NAt5IKtuqOZy?L&lsOO)7{eq?qi{GK6f^z9mY77StS?npQ54DqMea_H zt^7_|$O|;Kn4!CFo5T)e3PHIfm#k72$qe(MQlQWYPzXb(N?;$iakMBPB7qy#6mjHX z9<;)gv(1OlXn8i~3_3A(2PTvo`k`0#WxZejaei$EbLJDxJ1KrAc7@{E;{t;Q9*8NV z5pkzw378OzcV5+mfdD4XHuFRxQ0qnyMnjJ3U5!kr8ai)OmS`3Aw2{#&kckP|%9N!U z29EYQUL)KC3q9PPxS9iB5sbc$W2;ksy5_j?r7=kL;o{2!Fq^xXgTt&oaEXjgiW@rj z=!Vy)8H}jHIzL)eo)|k=Jl`D-M3QApdi51wMspr*)|bIV*b-z47;Ls``@Dk>EC_Te z(5awzZpAI!j6CDJ!uUJHmE!P#E^q=3hrYyeQn`!cy_a) zUNa{M8*L&m-|cbTXWt;grbIB(1>5%j>Mn{b-sc0y4z}_BgF7iuuxj{3p>S*)vZUp< zsp#tGdfeGu?GcGQCkgIXOaNQ^viuvp91yuRXBKfu7fL6v1cnZYM{W}MB9s-!u#Y@( z)grjUeiUqQ3c$CbaUKp1mwr9^JfgH;casO>S#=fXom;@4Jy@~W&9Xix2~zCBmpUn+?A6ufVdoaQ(V>H-L!lvKDPCa&guYD2-&H0;Y7uIl8LS z2elG*s?b+EoFZ3=#M#VX5E2QEO~-vIYXKD#=}fY8)k2LGHx{a`PTai1ZoIts;NbhY zp0wqTPYO_Z?c)Ncjn{QB^`lOF$>v_ffQbRaTTGLA*bS4UOn=f)atdfTLl5i#GQdSa zKmvqGS*?c;7*5{Gkcm7&J-<1_GYHODVg0E~6w~x+2pI9g*q}VuSpfD&Q>!qulA27A zmb5zJT&WsEC#Ok97l!-g_2Ep&L_rh&8 z(t_ZYa=_9&0oOs0{%tN_+~3)%HWdz&`Cj??>0@^eBy1kPgXlm@ zPNjQD-?n>1bs6jSrs_rk2PiiLRf^Tb8YW7kF2mJ_jza`Qoub?2ifC^D92QW%ER|9C7eF zlrfZ^^r4=FsPa#E<>$i&k`iR;nbJGzSmdjKfEC?X0!Uvk1XKw9-pxjMw}SYwvE~Zf z!O1l})eg6FtB{lSAZ6R)TltikqIXpfTIaMoj9lyaX-e!^$BKTg&*)ll(AgQ*-LV> zMyzF_+98@&9kXc-!+P|_n7*WTP4(Q-PHLD6lU9dpmTOkJuSYCkTHHvnx z*uX$S)*VI#O|ri^z@IuAAfM*K5)$3FW$b65G0Ngm2u}yXu@Sw)r^t-JsqhBb;$!Yt z3UC(O-QaGqTzwKYC*(W5D$_*2csC6 z{%2e{p@e1>wUZ}ciET?@=Fphu;yqI>b6t2phv1uhZ-p)( zo>(__uFyp-dqi&|v2q3INpdoQKwzmr8K5h~C%veUa6mxpulF?JD9AW4F@%q(mSgCj z;8by9bLP@x?-dWnGt4M6Mpffs78p@oNC8zh3F|V4dfBf#?{Ke-H z^Cg6|1H9JPsBBk>s}gJmb32o$(gzu;20Kg-qfwoZ4tqvb;BBL-TxEUHLir|u7e2fw zkY%tQRvrRb{?*2XU5G*70rc=%H5t2p4YOl`p{$B}l3qOA@Kdv3xIi#wRXY7P4jKb5 zqoXDCa$h>*S-oI-Q|S0BPSjq^-H6nV;a42%-n;?o@VO<-Q5};0)+H51L)1#^S@-OJ z*mL_7#U)8Z%aoc@2R;J!bgN2YPFmRv9}o;=ajl&o+yV53ee=%epiGkb(V4j5ODm|$XPMIFZfej7uk0<3M~utv2V0@&0VMk<#={7Pj6YloY~s=HQVgQr zxm77v(Z^V-i5#)@q$T>M(@o1Wmmb9d{S|ocskuejuO7w0?N9_u5FHLb&gP52!D9(e zn|Y%4Zzs)x!mL=7JplfyXMuC3Si~+q(kDD(9^z}h#E-QlRUbAYG)ID>$1d_iK=doO zs;UG5gy>e(oP9f(Mr>#N_0prXT33@i!0$OuH#4S&vOOX`l(ojKNa+E@!#;A`9afCa zviv*M%SW&d%lH9dA%ML&7KLS&$|`V(^59H##@wlr%*G`96^6YR9@+nmwfL~hU-$oW z&ODce8}fgwGp6_&%~^A2_opo5ZSxkN_~fsj?fY!)o9*|EE;*cJ-P^p-YQtN5>oaYe zZOgkK*kq($u2?tmDpJsWK_x4=wYIHB^nG!jW!Cxt{g7(+T{Yl4c_?tH4LGZMSNjnf ztE>NcOXxLRsr(a9K$U|B58^qfYl%CO#VgMaTbR(c-};i>nG{&Lc}XlfV24|RE*JTo zp7;av6<*>&aUW1;f(z%};wv^lV3-5^J8zqxXWVFla02SpCAA|S_`&)R&a?;;q;3WG zZU|KOmt-K6MIOyqFd(CA`=<=UFppI;4Ih%wubnqH~ahZgMYMK}=Pja$|2P1Ox z48^R#PSbY7s|`?2z}pjig?}KB56U4(h88#?ig~YYS)O;mZR1D@1@WS_nV(5{ z{y<5ouL6F=@M3bl^$G%km6|W6ldAE{P757iAFpV=*B*;^6QPe8bVls-7jK z!)?B0nPub20n+!G;D;F5XNua1;F!Ql$@{6vs5b``EdfzmG4U#ag86|yp zt5D|X?p&Z7{QCp*i0k>@Iyj>_zd4YSfqD?{lL>!yw@^-dM_GBu|IFfJotF6R<|4L`enGrn2#WE}@k;9;->*s4F>Z zAUrV{c1gTl^dQE@aicDANPg3;IM8<}#Rj5R{0cSXt(f?5Q53uKm|^_IsEvuDK%)#J zR@BCGT1T7ed*|PH<~#|?U|(|4@IUE{*E!J>s`vK?b6RET7P1%2sValAsS-!reZpVa zgS)uq@DmSE%^iD$NpES~f!;j#6o1-lXt@{6asTdzR&r(?*&JA)zsbsp$)GSCdY~}J zTbv#oD*P3RzzM^}1-fyf2N!K{Ms8quFR+R0IkcmuWbD3U4TW*N_Q4$YZA5|iW&HCt zj<>xDiOOhy6L^FX?^tu@<0dS{RT;Q*pcO#2QH!8<6G3+gPt@S|lHa^(6Zi2g;S&DB zIU7^a1DsLdv&lz6x>*tP#M^rewoQIn5?f1yhQ$}h3|y_XF&DSLf$V&bLCV0Hj|M5~ zI-m!)aDeDb>?I7rGJ;R)K$s2UY4)SND=7>T_s1;`3X$2%oAS6P`KH z`jFp%PG!U63Ckk*VI^MFcXU0*#`I_n)EnQ4)@uw@+C4>F(kDC-3b$O9k(`fiy~>t2 z)}k+|vzNq2MB};UdjmTTPs85=xAD=HGTOH;dMGoD=iNFUQd8O=yAU|6^SzDx4(UX= zK0$x`#4%J0LRiqqg5{AEF$}0m`tqvabe{T>B6B}lNF!8kCL@3u(Flc-H|jwNNi}LJ zvdwg$WkF#ec}a=2n8kI-t6M{ugRm4@7DePa7+0Zn9a#0$wnjxnuo{%QV3vN`8)5L&HS{nc~NBhr67@#}Vj~E(S(d{JqxKaK9 zu0lR_nZd6_Ne5FpY4<)7=b51zQ49s8urRE;UW=v*a?X(C8NhfG$|fs_cF;HW_?hX94RSA87t0A z@|Yh|qDCzE&aKvEzMX*r>CJ9sI=H=GX+*>)i0!hm`2tXAxKf<)W+E8%V4)z{fpj^g z16|Wx4bG9(bCrGc;bMB&>#{SE7HBZ7Q8sgA@0ml5 z{E5`=S!yLonaKF4$h@7=(b+m(ir89U!w12!>Q=?2QMQ%Mv(E-qh5wC35a27Q99RJ# zUfm}tVZrSwbt+`enk+4HFLLK5!M@?bcs6tvT528j0`^~bw z#VwW$;j8KcXkP^FXaMzR4lsnCLPRRh4;&|V6jJXDuGO$nA`RWf9*9-d{5C7}#)ClH zg%D$yE4NKDD2verC8p^!L;20Y2CiV@lC$a|eUzuF=7dSRB%pC)t`D>W&A5Sfi~O?@ zXAGj<1pFdQdX|lOaaxsaj<&$4dujCD(lTE{pZ@z9t1NXK0$|{UunUMpitPjzZVL#m z9IQTu;DCUl6pow1Jn+GvP(Z@4yBW36hA2bgeU)`}_;jox>Ylckp*1R=3r%cS(ov{aIs3Nc1zzypQjLlFycLP4aC9RXY zfI#X0BkWD!qB^#H;qSed+(^RJfbk&Lfuk}QIpV+<3}c^&LcoFKL%{(=FxuwONMsNh z`&|zQK^cx9QG#>_`CW-e5s-ikVqXzOP-r*`G%`g%n#o3JriLEgs;a$rZ!qV5zqPw| z?V}A#EI!JffIF5w$ok}=sE&30^KwH1u&*>!6 z=JMn!LArvxPWs%w%&p@Y{bIZ`Ir7xwlNXP(?wOcg^L$>YuVocv{A`ctnaZ*-wwKA z=|$RIO@VZxI{>IP_=3~xSAV$ko4~@*d!hGC4#W!TcDNnCp1ZZlJ!9aeam0qD_UQ@Q zePuh{09hYE^7ox;a)%AWh&sCW89>@6Q#?Dnrf!E17i|r^m(MxdzvMx4*uF4;L`I(? z0Lw8RhMN4RMy)e9``7TPjSteK-Ks5mv9f^eI*~(lw5ZqgN3ZTD--x zRpQF-Peik)`F-8$E2;tEY|i-e`cZE8mjZrwZq%3o=eP8fs7ruLCP+7o^f)ncFr$!r z{D~|g6|5TuGYF#zHYepP>!nd|N28vms51C173yZr>$iNRcQt^nB?ZnYyJvpRSLZDW zm;aaN<^#IkTEQUsiQuu_y~3C7>KYR(V@Lajp)G>S5Y^OhQ%TWQxUZiWoVoOb&dJXL z^eVmpWajEqd;IR1HhENMZW8quX&&Xz{&SPP)J&bkZ>UgD7|H+29|#Z(HH#|;F7kWt zMNN*zTs;qC@AE%YgU`vp$@?wIKs5L!C92IfW~fFL(=}5WsF*T1vd_2)&If}KdVLI! zD1VcpG|E-RbSaK6ZMnL)6rG(QAKGW|Fy|m*C(<|i448l$>GnZ{^Un|4B~Sb zmrs5M-%YNaxXf5+g%TH$tgvMyIJJ;{If zxfli-CC#a{vHrtq4_FE!?RJKl6mshm?cvL*gDzy5xScC0I`KsCh2_+3(4xm-E#7*O zz?@3&101zIb}rR|bqV-iP*b)*KOKUb%N_VJA>t)H2w^gox9LG&n&xd}ltQS~<4onN zE{CZn+)7pNmYn^^70&o^A4PgfgyJ5@t?I`F0q~a~qdRZc;qD}XNmG$=#E(0~sRIY~ z?T0Jw;yy=Ab9Wz1Ci`h4&Gj(lgwfPGjnZhWful(4|LD|%oTBGH{Ak#)_0f;9MaI|A zU$|xeK5xl*{U^%^j}sH{xhQ<4nqu970~Dw+BPz~OI~JqC@N zSKHW|FP$qO_5bdXM|IT>x7&-vSGiq1A9am6u09gk8U8j@nzYVWOs=NeSqB_Lghz?0 zfzjux2vrL3Ux68uBDz7)Q^2l6eLjh)m3Cdv-92%c_?}2-DMV~Qa(!Q9hY$ziylQ>k zXFAN+hhMRs)PYpyGfP$kI=KnABY3$d&B3r`I6W}a3;ksfz9j2gMkackq5EPnf4y~$ zV}H&_SU$-2stbw$*uw8Kn$-UOhc)mem|FPjLze~)FQU6yUKaD_A9tT^O!)q9i;~tZ z|D*BREk_O8{vW@Oclj>+W8r6}oBy|A{r}$lKSrwKs^0_^i&Z-{(|`LPYyWfoe_N*p z(DKykyA^knuxzXAS|6D+l5`hE+Sf;>+?}R^byH3wNs<*;Do?lJz^RRrjM0DxMT&-g z+ssiOio{9QTU|)<%VAcUPvw=0E|?!bHmWhRj9sH!^WcWt)ECir^9R$S_XtP)XTS4# zaXhemWY3k#!MoeMr*1q$C){|}71EYz5ebLjKfa3`msfon_vq2<*YAEfi#ERDeYWDU z(;%$kHpey_cNF#H#<~0E5Lcj@m%|-%B(%g)^^> z)FnnrS&DL89Mf;WA2)~@GvmMZ0k&0IMImSQIOm)8tR5|n8HCdvWKy@`=VWiAOkEM9%7BiBf?&Q~xs_Xf$QZzHu z%7GMq>s)gnzUvkKbS~U%#z(2(Pj!cLH0W(YSkFE0Wj1TmZZpo60g3!De`YEFU7%)H z%y_=K&`8}BIQQB}RSf`YDXRWW{6Q&ye2H@0P4mx9>OP~H=5EzZA#j1DsUpsPX}5Cq z;w9(LLpIqXWXITQD!RfT(Chx`u_upL7(nh6e#>K$K%3^{S@@~qjWogh zz9pI#QQtj{g7Xd@%Qj}lS=1{}Gn#D{YMyUWPi%tc;13z_M{{GwIO=HrWSH8*QEe0e zS^p_yJJt)h39Tq>9RlqEMPxLGrI7R0Q+6-rw`om1ziCvpLUY?lRV15RzO0o${rB#SdcC{@MhABu&Ic zj!DU`NLfRqxHB9cDk_%q>F1P zb;Wv%Gjhe_CrcWZ#Eh@w%+#hRf4j#Y0F7*moa$Hgw8p4j_{>apYcisf@@u5{0^2OQ z$dzEnOhi;NwVE#NwYQlXkmNjKG(3GxAH-EMQ)wS$G>y~ zMkmQ5Cwje!@wgiR#UHdLw@zU@2r86aaR! zVK(=ZLtE>}@Uy^}sa-x$7qSWnsePF&Z>MWQsQ%$mwRQCTm>f0T2C zZcCNNJ|T?)-8RF2`!w4?f2j7nD?~A`$w!R`Wdz__uWMh7{EBE|5-?>mMYGF9>ZIv@ zi_v=TuFQ)2+rq*FW#e5PZz{{4MFtBO<`z~#ss`MRTXQHNs8Od@xOGH!1S;#S6z(cr zKE7n~Jb&0{ifV@W?|d}y(I`jh7QG1)UTeV2ODc9HvY?@-Ob5EWYl{M@RsP1RjhYr3 z8>G?JmPWdkETOAa+5PE`tZ6}ooT+=My7j#zy0S3stUSB=>)O4-GtC2oah8z>p;Urh z^=gZ_HUV)u(p4CfC{Zy=N6t*A(eOP7sv6MM>Ijtg*fknYMgeJ?fT~^5O6?L#8F%F) zNwkupLKC~@c^IX6r?1R=Uuc6MG4?R^4%?n%s=@Cv>*i&D?QU90Q6XjN1*0Y8IMv9( z4Tj5D4VSj@qw8FaFRCFHG~%p!^zjeB-^SxgY<`2^ZKwKefiaLg&6H`JJ@q#dEIBKYuYwNjXk4(xV?S9Rhg(|xgr0`xVr%k3u6dsbBWo-lw-z%J2kEYmaCRT;hKIQC)D&8BYHc7@br$|NB* zH*Bps3kMsvbt-O*@4=Fi6O~)F@9M|yg*PSpcpI#iWnS3x_=X?7iO!}h;f0M@Ipn}q zo87CZwA1P|ZU#4htktiO<*OoxBJiY-bMs64!#*;O4 zb!1hRiQ6*guKmucVx-=Cs^20q_zE=eR$*=Z7VRC!p;3d@zuzJ-_)Wl_`}OJf%I=;% zp0hQ?@Iv--v>ijPLF@-koG$B z-%cxAjMUYtcONC<-C>CqR^GgFNk}1i{3hR!2QL(Rk(`J4@>NdfUyo;9Od`V4v+i1~ zK;6&6%A?qw7)V(kTp4{6iEHUkN$)H?HRaMZJ8Cz|Mo3e zwhS!~O|)@ZmD8}TmXh?q@+fzduWvHz$gbT)2N;uWUR&*+ar1dcRz^ipeP>(0jK_A= z=C^BBVcg6LIlgLopsZmV1i@4N;EICN_CPQPuIV(msAL~GR8uP6QhpX(xqRvSr}1RL zu-unA)I`#&kLF#gD_GcT-&uI`n0w8Qy# zBD+A%P+l#|@!LnV>+vtkVIyQq`Eu{X#W{}#)Z6NQ3uybFCR-N!dE{Ge^LE;rUHCuG zZho!NRCn%g^#3UE-yBVy7P~rR_brv-#dWdkVkacY`70AwB6zM(b;meols3y3$GHv6 z#3rM_*5P%s+w#2#!KTMkX+toT9AK5altO|Aq$Mp#P_Gtx7RQ!Wq`BQ*xByfWLQm78 zZ4b#dOxe zuFXMJPvMxrSg^?ST*A?{S7GI%6@;OS@yGzgx;lSmnFvzpg3nm`0_a~1@oW9C55Zlt zK$xCBeEL-_Bd5PvsY?OMevn3F>24aymrhtoAK+8%)^{UPy>x5`N+LSBaGFs;P1;I= z?WFIMkYDZDQwy&F7_caz82ng)F@R7rPi+i;X*b5`W&|~xM0IPo?6A{w!}rpI8}GHV z_U$8B(*$VE6%f~a`;J03kvo}>Efb}lWni!f8aP0LKiC`fIG;w5b?Pw(+$jt{1-P>D zKHN+!S=_Ar+5Ms+Pt^wcbKGBiGP$rD3pt57mD#__ccbsdhfjR(1^IE(m(JbfawbP| z1*(@t!iXt%@hN+Mkc!r#!;0RS-ckN!tLAOD>IGkOoC2Y^&PmV6~qmp-GbOIKft7oXUU=!RdE3I!0gJ4 zr&%Wu^8}HSH83MG;#EY%@L*oxTtJ9-cBT>K#Tn2=475Q9C2mxP}XWKda+bMe|tuaCN4 ztQpH6&rRXxQHS!Fj78bL$~P>wGyIISEsGl_=+ryoEJ5IodLa)^MR(4YPlgT;w|EZU znrxo^OLXyrLy+4QlOrufhkdfR_XM30XNKGI=*UK2)}CSk$O9`eh}&VU>^KY`OCLs= zM~Ri#gAsf-{KJMNXy0yH9T>gXQ@vmxQjr~jJ10D-z@+Ig=$L+GsDpFhn;n6$=@w{T zIeA--WTNFo%L_OT0p5!uE)%(_18(-Jo4Fj5iQJ&;ob*Pa>wp`?QwKI)zZb9mtVy_b z)_n*60_;RrgJ4IXUgb_07mRe7IHF(K`XbVP`0J5B6dtZVrB|^NB8ySfW#q?dNHi0? zn-Ea|5VnU)6dbmOBe3toie(eI=hXWeg&#+lADAaF_P0T@fwgb= z;BZ_2@5@0r1|kKC&RbNmZX~(Dwo0~Wc+s#O{7^_FD)a$ltxsmYtxwnkSyZQ@TplVN zPW~-xO6sc=%9`44l%qVezujC;Jy7f}tQXnQFIbd>o-R*e^fs%kq3XJE9QC%(PvxOko z*F{*O0v=dFLe;k_f65OKXeBiDfLTIlJQm}YO9!0&R$(wz^QsF4Yi}>YtM!X7z!zs% z*WQSS$_XR@olc#MK*RCB{8ss~tNs4Ap?Tu!XP%HJ$cv>!kcS?JsyCQsB3AocI2Kc1 z)I3iB!TLiGd#$w7xe+D|6xB|s1ZTkGjIYp?Fli)KpeDq5&uKxP^=PxN#z#dP`ltBg9lqhiNK~k%O z;P&a@tbU?#qOmU6Bge9$k~?dq2h4;h7CH{l@6yfJHj{ST2LKe6K0QGDpn4-xXNpw! zH1EV36$foqa8&J_XF>>3|$7t^Ps(kxNLhe&@9v+svBkA-b2n@UF2*A}G2DAe>OF zgk`u7NJqqM{)fGo|AEkxz`a>^Ry7o5MW#sEJF1?Miq5VT#GCab;1zAMA-f&fs*SZ~ zA>%q(B#MmI4}h0|w$(8Z>Pnim1=b3{0tSW#v2U7~So5@Ptvyue;ZSo3p9f?PIL$vw zTPfov>0PBWzAw$3+ zUFk;Q*IoAmABOHa|AMF?kK4u%Sa9JP%Dl;!tCwSXlw8 zX1j1jt00^qO@ZQXWdf|;YUDSW>6(QA(T&*|God6a$}emjK#b91Rs&9o z#xX%tSlz0#!t4R%WF2J)o*>do9IsyU^DO=jTzwIZ6wJrlg$gbKbV>_J%u=9$R7|#k zT|?v^GW8tZBbDFd%*pu*1OA+k<|0R}-X@hJN+C=ZgSm+Q4%9D%7zT)jfNn&BGZ!i( z@S146SL7^NkI`Y;A25zh)_kv)?bQ42%xgDorW|I`Sf1{ zi_Xf=K6?Ds>2HuA-kh|R|AJ{4@F(rUM6N#BEBK)PM>j&GC{7N z&zO1484G&R_eB z&*ZI`Wnby(K6EP3<9(2spHxlT@nFO24}VQ;vXSI!+FAp%%^bOM4uyxe^DVMDR~-3w zayhLpgu{d4$qA|clzSEJZO|reOY7?tkp@0B8QY{D1n5+b%1HCBRioU-R}Obasg;F$ zu|v5X+5E7~H}S#NZ@1G5HcG*0Lqa>6U_A2Vm{UP(N1GJ>VT@Cxc(u{*9^>_~971Ma zKzsn^aQVOck8nEhTFjSJOkqelrU}KyEvZ1t76;cMb~Or-A4;q_2nBh_xdOrd7r0%q zo%&~XNg%S4@yC!~7-0^ai1mjOCZ{;YS@ztI1Ek~MUzTJpDgux;36RK9Z!|$%FWXFu5PR9m~zk<6@s(n>OgbL-;CMPu|?RB|HOzO8uz$&OF~5@HmW2qN>PUBhM55wc1_ zkL*3x`t7(>-uy=L_SIf_{y7_1%=ox&s>xs zCG1>_BOCpI(n-r^iQoO`e8q}Kx`gx*yRcnrBOrpiGdeFyD&tjN;HauTzs}h?ksGhR zyj1o1dG+N+q5iD_v$or4KYkVGK6P9lNyW73YqZgPhP zDf#{)oO|&k>Rgcy=Elajo^(bc>BsIVa#8W2?{N%mwQ&W}{Wt*U^}&>(uTYN_WW+|B z`U=CRGPpRPOM<+(p-5~u_govi5HC_CHnIZb;6&AfLo->-xGMqhA+Q7&5&SeXAImPp z$D(~c+Q~+*gkGE8CTrLO#rmqEouhfwt!Wp{)QB_}l`ni~c1U1~%wq)WCDI8&aclr1 z_25&}Z;}OSz9J#O7+6vfXDTCPn+|!4R_Gva6nt^&Z8Y2ku3VoVW~8E>%T<1>s^SXP z+$NL3;y?GhP_&F|?ng;No^eU4#MN&F@<+)%k*62lqQ@?#Xb)_o!mAJBD%s$BD>g56 zewE`t=?{JO}Yo1{5ma0Wb;SGolrDU1!WbrKUBw>e?dEX2M3qt+vK4oCT zr54owZI1;n$T#hiOl9nzn4Vfi9g*xbTN}mjd2yd~W_L_7UdbeV$$KD>!ZOg8-)pI` zc1RPlRyJkF(rnv}xtV=-wc+FPUa61zwNO1LngyoEe6@nF3gc@6HA8`#S@HNi5g1e# zLxT$UTC~(YwkngD8npNMWqR?_E}9u=I0^YMIiBjo)*5GK2FOBo(u!<(Sx%a*l}2bh z&?i0c2A1UgvIW8BvPXT3(`_LMS zWs;|lZORUq8Q7FH;#{S==SAwVFwMlMrYBG{B~DF4Pi0(VY7Go0F3G^1nR<*OxARH{ znwv68A)tT1$K1flA|xm~?UO98fxhiEe@psg1>nJgX{LEhF`V)syZagru`@3qs8HNz zHkF~Q#?La`S4E7qd@nnAOWEyoTmLukk0KA*?KH@KZdON|X;_I%gH>74Uf9JP#VH48 z&rf)d+BQ?`c4PE(#7;#1{CuB{Y%=_S(1`}U_An|z#z0(Yn;EQRky(23?w%0Z+H>=`BL+AIyvfF^0P_9)3AFygMsSt#j9pOPW zreQo1aPul&w9x;k%PI~!&$tOe=Up1$wKiBEHsRg^RlAm#TC^XO4!TN6w8WJ$#VzYtch74Tq+KTk5j#U(xwkRYN)4yg6(CP9InekGR2_Kcu#y|KR|K zh2_Gcdet>)Obp3M$b>yIUfMOtWdW37l-3>M@1-$&ZKs1@l?h)osIHxnNtc&lejSu* zpt4C`ybf_&DLx2s%1sL6_Qu5g8qDFmDzkmtk#zuiat^H;OR%K^{h~AwC2wh33Eusabe8Q*?DP7u3MhMNp zfm=d4M4+QjV}!=cU(|OF_RB(o!<27pIBJ!T@`Yx`ldrkQ@6Sg(P{6{vdB<~Fa6c8M zmZaTA7)%Axj=zCV)`R&yDK;8-K3sIKdM)UP(_cV$3FCws56Z{#v`F;A#gNp(Hl!e* ztNjqyjZ_7=(sXh9$_>{0f_~}yrZyYZYhdz04TAeJkESAlmLzDbuj*@-JbermIq~&S z&mkU?EV^_J#&ze_Knvh+cX?CI=@9Df$NjxbzkdTb zVNrSW`u9gH#SYpX>k5CYb}$)nufoA0vBTtuyIB3Q2!<=&bmm?bx!IH8GH?uvo%QFU zj0?pzMQA}A)%hY-pyu7QX4Xe3)hI^QFEn!0e$H&;Xxy#{_ADdzJd~Z=(nIkCam{gHz8j$As?d`5{D2iRN`opYbOtnJQs(z z5N~t#m7R911>Z!-1duIn4Y4TU}nN=jIs7vlil-NGdrT=+q0FSQ6$e&#!zQ!5tDO4khtQ)1PMPp5KYRiFFvT_xZ? zLiFZQ{ssvQUec!=6=GJ$mXBu@UxVYgV1YBEHykj70d)-2iQGu!P?~4MwaK$g^?uLM zf0dG}It#(A+&mCrN-m56=jzYi#A`v!hHP+EVI!i2@d$2NC_wg(2T@Yg`4yLg@e)upylgBmO;mhvxg z)ej@Riur`42bqCS7|+CNyC_aO$ca10`gkT>@a%|hNnA}dSc!aHX3&zm!dL72A|}f$ z;K9VcrMWL733<$TJvEc=izVJa~wPT9wQgCvq#Dw*%8NaxL+>VxTbGjQgCS>$$h;3HSu73~Vey zyvXNcq?Z_diUdPxbf+NCEQ6|~-)DLEVD+gJ7UZZvPz zJY(*8^+-vS)S0?WR`vZA_#A2dM4p=eclfM&#etYDIQeG(XPuac^w(+g7 z=SqDkwiJ(Het@2ezA>zq6Dd1}QqBsyr4R^<_QW*UD6FxG%QEo5%S@%%$LUB#(djV8 zM&A~e%Q95scIjTByixQK7d_rkDpJj~i_}FTO)LMBsG+m4%+{(F_c9=>l5pH3o_i$7 zvPD#WSM- zqVSy|CwoTck=yc^D%8W_8?U)~l=iHNk1av@&zT>zW) zpLeF@$zpyr3gf&=sW9^HR1FNtYIe(>_ccJzfy-vdU52yO(nS{pIfZC!4;&`?TR@4i zR_!y4PcS@%$XUe$yVh<&0xi{hJl+=;hh5-WLV-y0z%xTruhG}I?1ZB}NTew!nQon{ z6-HKJ9Pk2*gSdGe2hGEH_|S5lxTEwr&?5l;h}LbOIx4W@5NjP7_0St+Yc(x*1h;U+ zeOi7DyhJ1L8kLQ;tFk(ps9+t(*(@w1$k|M@Y3Mf-?mhEo9}ip|_G&-9DkJ$L@t?PE zfBF5cl5;VQ&c@r;c$fT=&CgGmQvCAn@2P*<`a~D#4D#$SMl(S2prt&WJF)LUQq2DM ze+xJp_%~L+G4C zi1mcV;w{;IGNW-T!p5%l?@7myx~Ywr_rpyx9=p-)WX9RY&i4UR$OMBg1Jo4Z6Cy}e zCxHm18X&8Tf5jvp45AV_`enM=wYsHy-{|Cy$GV4C-L%V2H=`h~0Iz5vNWeVk04fz| zf~U2BZ@czF{MzeJcRW*0)Zg=onNkJv$KGBU6>yYC52s05XpSB8gp`?hYAH=ErMO3^ z=Yt2mV|=ID+@WV3S(bXzm|F}u^atrW8$i%kL3jbIS}Ii_U8rgC;hAmfH~Fa=8>Qv zokmg81uQXi^hkmytR6e}q+>|rbE#h;){?CbPn@F|V5!~rwE)f-*{kP2@;rx|BLXT* zjvUU?Z&B3xj-YqQT0bH=Rh}K&=GuC=?I|dBaoQ_T=f|RUL+MU^#*l zr}$s3Pzqk8DA5XbO4jo94k2C8GMQCWxd5&h}yhz;?rMXc7c(GoQ$^PQgleceiQA!;2 z6vIROrIq1-@J2h9HRZ+so)WyL6_if7=TqV-YH7|lneayt$QeJ>#k!vZp%3Phga#FZ zYlnumHhX)9p~#gTZh&FK0+YQXKsRb_F1izw2al;e*Cd4gllJ*R2b}fkr6BTy3g^b6 zb0|THhMEuD0bpPm0KdQpG8G*jvYP==~>Y7Y(VT*XfZHC?x-++wR2>(enm}jq!$&S zYv{jS3(zwcPr?azr~-xx9rJ92copz;BU&J#@G}6W4MJ7|-ISJ2t!x$azCyVTe-eaF z{wV>WFQFKn^IwTPNJ{yCs5%52+gVFoOr9?66n`86=Man{q@MsqO{byxz(MU{9NR8- z9XP0CZ=UUQzA@i%;2_q8&`E!9)gctc_lBo%ye=)pX^Qpl=B-?$4dqj}AtES`7#c!* zSP`TM{#b5>PQGk*_jL2N$C3P^BV3(^t*`&Iv_b!x$(O^SEyK544?^{J5FM#(h{&3> zK|B3*9{l*5f8~Rg;g`ek|Ltx%_9h5A*4|`-T#h`RJ0e2WmQ;L?eCCeFS^DYdM!gXn zMo9;+3~6x>*H-1EAVVT>O(uW>=XNYrwBejPkb-zsaZZp9DPQtHrA#x@j5~L0nm6^& zrI;2%XA^Sj%je1LFIxH)9E08ts-C9Tv#bXvphVY!{sq^86q6$Wh-x_33(-dd!lD=t)JLf#iq-QKQs&nEq5Hi9K$!Le z5bxpuDT(22r4aA{0sO80E0Y2J5S{W5yw6$au!;;Wf1WgVCSo$dkhy?cjIO-jvl-n4 zR<|bqqAjTiG`G>)v>b>>5iXOq@fzN5#MJMtw}zW{4$K}f8a}4?r*k`j66z~Gp0-hJ zjzE+pW1>$e^8!p2VrKv&0uR|?TAm6QWLr_>23kb19}%W1wExIZh|7CUx85g@1BJl` z!+nT!v9>f7Ssc_3Vh<(L*3|OduU{AjsNC1yG5!S$HUYI9a1?l> zrztjKX5uw&#z*GEHiE^vekryxBUNr^p*%~_bDL?~^L z(GHgTk2)AocK1maN{BX5h9X$4;1sYd^Vjqi9Mk+04laM z2T<V_-eT5B}8Bcu+TU=$MlTG zE>Ym6;5!|H(s25*GtF4IGpgE|EK0Wo;CN+&kP!|_2wk1_&!_y;-Ei&#;S2rQ^xJeT zb>)7SeaD^lpTNO48Q-QGzQtxWaOi-?w$n=w9Jg=3bGn3}bHSnWIDs_{Xev z6x3NpY!DCJjEej+J#b0xxbETbxIDW@9s=S_#HJd$0xGb)AYDrHP(ZzbZ2iY5F=$BM z^aS%U*ZcbU;2vR*=d6j^U`#C6-6$@2W7sgR%MFh!vU`LWTzDDZ>|TG)4`31*;$%=Z zLBSiH!`cA(d%m?xf7B)73dpmmW|!@<`)K+{tk&4kxnt+Z@_CT9gBpVOqkR$L69dNv z@j$*K=}9F*5hT+*wV?KUocJ}Jq&?2G2T4Yni6Wu8UZ|Y7B1$t7(e5|nho5v|J4)+N zSs{Kcql^jW3FZzciEv8c=VS;gsdS|03L-#lojPqf)Vkakex@DNv&Vb1AFchg<8azZ zfBk?x=YG<votPs2)zg3H<~O3ux(8CiGp9TD;W#5 z3J8$ctk=JwyEE=b+Vi7)z(l|x)^E!dK@6ax_onSGgm680XOD5sD!~j&kD=7X-Bk-6_!7 zg0RM)9o@2CJJtrV=KXMcxn0A}ZoaC1RHW{o_TkIt@1{qNpyA+t+O?)W`ZH8^=UvBpZ>1*IMTpH+1mwn47u|{mx z^N3Petk#~aICB#8J?*%cN;!@$1QVBmpu~5;FuM4h6Nn4d(=-C;=I1X9Qt}^bweso$ z08?(fzHxg`4Rr26$IkepZ78J)NgGm;-O!%^Y`wm_AYE|Em|olZ`ZCfL7m_^l_vh~Z zlAMdu5UyiPod%@YUlG#`+hCxZ7a#h4^TEZVuoL5A_XziWu(J`+$5HxTi3P(EG8nB; zuGgaME`nuzhsZ-P&{~IA2NAF?PAYJ#7ckcos&cT?VZq?B`Ot^x|He>tCmgGyZ^9a_W0QzqI3#ojtf^pdp;vH=ZgCXiE2m{i!PGuaeD^)|fS>U%{8+E)SG z6&~SFmH=;i&{P}nX!}6b-RunU8KYlc``$VEpFatln=7UQDmqJ6F0$hM`HxOdB+Hll zukD4Et<(Q)^U>!!)?fJchvvsm9zOw8igv)wd1l2zKEZns{>yi!6hH(*3j=74zb`A?%Yh9_Lprp8mvM~ zZpwLgn5AeBJ}hnXVl4d-<(8vs+XAv=ri}L@E1@8iw&Y3QyNOS+yd}uGjBH zrv3X%Z;zn?07e>QcEJVlf}X?Ddulh0>wz8%-;E3D0Ezl0W!zbjqx@F=)M!;CPTN7i z%}erIALqBeUt_`tNWgT_xTm_#N0B4J7qWkGT+CdP+y=dHm-ek8gW$a*ipa7juw<~_ zsd9HTLE|k0*iRIx_pERAX(3& zBjtc60q7-#O@(?^QzbpSM%|Zl==T}EDJvmJy{ zRVvy83UKo|8}ttA%SeU=FSlVkWXfP7s)yPnrY3jW+S}+*(Z-JEd-~TB=McM z=Q+Qae$X6c3PHbt6OMD1JYH=x)mV5w8NClYz;Ew@b? zRI;G}3sDV5G*XL2*7p95pAe0}Ps!E|1IM#JU;)hGzY@VHb?SCpG_{3_(Me_EwwNa? zIK4^2^V2ioXH#HxmR8)t(_@xhGlqfaoYh^u($`R9;#0?-h$jRpy9ja2YL!6M+cet7 zS*?Aw|4UBdbiw6=T@G2Vdc!tyb!VG=ph4iwN*!F(xNy6ei3d~ioathrQDweLIS~C; z>OAVtNnw>>23`pL2k9K6?kP}!-#d{3TqK1SS57QVWs0<}FN4)b0dg{DL6L&fum*UA zTX_oV)49QK+EA1Q8CFy_&bwomX)d-5gF5$_{JA&lJQQ`uRRdgw1{AuG#Cll2C9AaU zDAJ&LS}0}`6VRn-{h=E}b}KU7ugHj$E1y?}$MkpEae@N{T7@I9Zp_nhW#e|iw64;5 zi!!}@#1OaWmo zM1+I&F*ml&q4I!Q0J>a|ohV6=w)}n-5vkQYDCF9rL{;uu)nEV>?`t0Mr{**>;x5gE zkFIYHs}`cF2?mP|wNL=lNb9Orml)h9TpGvOuy5!;Of$e#;8fzk|Ku9C_iCeds@huQ zcvZ8YTI14Ku%AK+9mzfhEt9svonPm%t6!}JVeigkEoNzC7sq(axfK@6id70gAKX1LRnO~{3em84Z^zI z@tf>bgH#qJBLRHI-7Djv59Q&DZfS6sfIqo}1Jq%2t(vj!IjN=>fV)*9rL$(jNL|UF z9aZP4UZf;p!)HZj+dzX;m=(dZjI)x>on=?-_IKDu@fOA6vZ_<$^?t}nE zSudqP@NB(RrJF4hKcQART9jQsWDc(9U*^;qfpzHfU+gXC!kdp?`VMWz$aXgtyPvMClAjO((T5YT7Pf2wQD%C>dP;wzttrrb0Yd?~Qq6m><- z+6!Y+nnt(G+B=DA2Bw!+)(pTNac;MKa2g%NdACj2wY*X>(f=aT4Rk>IB9a8&pbzv; zh@?y_$5uazRG$?ajVgNW`5lVh2BR=_sl4V*iZWDfqkH}}TJcvQO9`x`End1;I2L>_ z^_ToCQG*Y*rJm&?nU0DOvjYGxg9q3Wk|GLYPxEhfqgOH-Ivk@g>2)A?^%E|7hCuH{R9g%U7;vYs0W%iC?aWdU$0sIl~lgcDWYv3a$Z7$NWL3_bqblb!OUWAWT z<)+N8D|_JS1#YAGW$0w|c0f{_J5FopF;G2(*=C0T4eKjw`nw+CXRw@J4N;^x%WhNw z;NjvIt8Umn@AQ=|4i39o0W%-^We9>VQvAGjNKR)v>zexy?oB7KqN7UsYlM1=!N2strs*e(+-JTGpq&5BmTJCt)^FJLd6k->JGd^ zh^rAuV6ujD>ZM&cSU&xvbX#QUHuUe9l+z+$+-#FaIr@UW`^eDin?6bc@t{oe3~;!0^Sepzp;2>GD4 z3`NMxx?w3gEvhN)KGreX_K12=*hGg0$I%O-h1U^jC9_{aU8)VVk7%5TTiR{e0eS}s z8#(m@Tn9Y^t9GSR=m}2SFm9>sqfSFvgBU(|1>`d2MZVlfQz_)n<=cxtbA)g5elV?qW_Ytt) zv_c#4KbK(vi&z{I9&_WF+|pYh{I-N8Q;B!Em+f;#43CSWrk-=bIJj|495RxT zER{B8lHa#>oD@ItXOaCW^+uVZ{(ObM`lt6-yp+1BUzlKhiF2X-hW4DhC>Xa(sgv8i z0-6R*pc2sS0#(m6gPfUd8mZ>DZl#er626O7Kjx_4az0sL*x0Ak37o^G?7Z-@GIDjY z{gN8N`D0?ok??r?btQW3@d4FVek%%-B$j@t$0Oa|9Rdo2S>D#qPYQ5o2XYt6eiVFb zmvc7mY@Fm%+JXVARB=pRgWru~#pkIrCCb8YOU~c5zx+0vx8!)_`gX^*)pb+fuoJCh zO=R4NA-O3$##AD@`K z+1X6V2kK*1gNK;2Z7w_nR?lLu`e*Y^{bju>9S z$3M;F(3z@vYuID>*zyARGx2%>vg_bo+@AZSh*rmb^!lr_%E_7Ghp&my)_Rp()A#SP zGk111_WjYxp`yHeHt@-d#6rEN`qTW2-F30WK1Q1toj$6wmVEV!aURIrOfz9lnz*SJ zCgxU|l8In@EhxYsG8^>LMNj>F<0EDAx>f7YEX*|9;l2hNGUZYn{-!6r+B|`rK~0Q{ zg3pJq*{6#SnlaOIVPfiT6V|eer)1YND+XY@tQu^^(rT+Kl79VmFF!KT4`a{rWMr-^1M^aC z9(II$;_L)7evjd)aAU4L%V0_z{RMg4jGnGR9R3=8>Sc6;pj>=#*daG>?pg^T%#K^5 z30@eM6HQk|lTYF4JF|*q4Tr*DZe~$S=fPpwuc2YD%EjNKzfrR_Lqfw!U{+-i_f|*S z1}d6|qcF#k%-KBeLcSv29R%|(t;qCLm;kMeHyT?PQ=LM81W&fk?!3SDh+ckt>zn%) z+|p~OEOIlS4fY3>mqC=C^vFz?B(qFm>f;J}!l~3DHwz^w%*BLRne>K7P+{uDbg$ce zekKOyXcF*~=mwi<>){URZ2;Y6f!3HO!2C>@?`VK#Lc&Z!9jC>3f@GARxNm8sDa?ta zmb0J`GZ&1;_-S}bA>fYzrd6A};+pnLdZH$9DLmoTvBw#`aQe*0acr0;>MMIk3p7W$ z^kPzl1OkKz)6}C2^I}=RjuE41m=q0|8cX}vmMEt^A0I580M~0 zeN-d6SC3cgSLLnXojA~TZzl?(M3+@=;^=(ml!$yu(aT`FPUTkGZZ1kd=fObAay7V z)?xkpUA*9g0E@zU6I7T`IkLQRwG5^RT%Z-rv)a5T{hDVGH4T}bkQ{=hJ2Uev2}14~ z14lduosI3|guz=W4A-xrp;45)m-@YN)u`|5mFy+4{81Sl4i01ys2z`PQ?WAWr)hMUP>i{TBXE>{auCGORN zwNsxJ<{DF*`ZlPg}(+YC+r}k9|TqW*0ksBoL4+S5i zO$g>q=&YBfbgO`msZ*#PGwAmhx%!EQihU+um4(@Em9sDX#gJle zZ$d6RKn_zu?{)Fl6O2+6%l{&6Zn%}zYK7oC30lSw(hx_U{8-HM)_yd{2~GMMaz?-! z80Hb}A&{T>_VQPjbkI!lAomE?8Ac<$Mhp!io%}!(4HN9w6{0i)yX|Evjkt>LJ5L`eT}*29F|So^xT$Ta-{Qqd3dON2u;--ZuV%znFZvk zFdr_t+6Hj3cygpfI15XT1mG*^kQ=%VxaX_?;YmLe(gw%{UlHVDm7s2?Fm=FvhtTyp z;L+j)K^YYRSs{RcX!lycAqJWKtSL9%0nQ4_b$hcH{Y^g_{-zgwK>~ob_VEroCvNt^ zf?8%hN=&#LuZ#aWAphg6UA)7R>*96R(W~aTO2o6+h_$Lwe|X~GQh~a z^xXSaK{_VbNvLKfi_On<^jj?)j99>7x zVZTi^AI7M@KT0<%sHXiXyq<2NsC-8AIh|lWy|$iSLbYM&1iB5w^%R=P+o%`vf#Wxv zA!pSuMw2;^GHaGsnc!Jp0D)0>NsbLrJ>9Pm#sQh8DT${iXM%Z04%6lY%-H-S6DBwk zgqntEm`{lDe8{9i#Y(`U-HQ=`Fk}oykpVjwz(NApGcD1i%i70)@PUj{WNrpqja#o! zTqBkzHVP<{pjTcaR8DQ;&-9AaW_)F!W};OyHL9KvYF@i(X16I+>kKTl&IJaSy`Kt3 zmMaZ1foJof`F1_&Xa*@gMH5?Gtcj1T*`Dts#lYM>@j-K8k%t2}FRI~?;#%>zb>s$N zQ7(84fagkCU38kcDm80*md!VHmW{bKm|N#-5i!ubJPM4%!8Z-&FD@0-n%Skfoi!D{ z+wJf=BdW?$5qrrEKvcjSM864`z(`mjhEy5u z0PGXDkql�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%0AxM>}TinBv*c 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 E4-?S?ng9R* diff --git a/packages/techdocs-cli/cypress/screenshots/backstage_serve.js/TechDocs Live Preview - Backstage Serve toMatchImageSnapshot - Backstage TechDocs Page #0 (1).png b/packages/techdocs-cli/cypress/screenshots/backstage_serve.js/TechDocs Live Preview - Backstage Serve toMatchImageSnapshot - Backstage TechDocs Page #0 (1).png deleted file mode 100644 index 3f1078345d73790e0758186b7690d9760a37a38c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 330242 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 d{XV-H5HxbnYVKYewt*{}-HY%0vJF diff --git a/packages/techdocs-cli/cypress/screenshots/backstage_serve.js/TechDocs Live Preview - Backstage Serve toMatchImageSnapshot - Backstage TechDocs Page #0 (2).png b/packages/techdocs-cli/cypress/screenshots/backstage_serve.js/TechDocs Live Preview - Backstage Serve toMatchImageSnapshot - Backstage TechDocs Page #0 (2).png deleted file mode 100644 index c576be51c57fc5803ec6b1aa1106683d9ccb565e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12319 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 d{XV-H5HxbnYVKYewt*{}-HY%0vJF diff --git a/packages/techdocs-cli/cypress/support/commands.js b/packages/techdocs-cli/cypress/support/commands.js deleted file mode 100644 index a8d6a5fdb7..0000000000 --- a/packages/techdocs-cli/cypress/support/commands.js +++ /dev/null @@ -1,40 +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. - */ - -// This example commands.js shows you how to -// create various custom commands and overwrite -// existing commands. -// -// For more comprehensive examples of custom -// commands please read more here: -// https://on.cypress.io/custom-commands -// *********************************************** -// -// -// -- This is a parent command -- -// Cypress.Commands.add('login', (email, password) => { ... }) -// -// -// -- This is a child command -- -// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) -// -// -// -- This is a dual command -- -// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) -// -// -// -- This will overwrite an existing command -- -// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) diff --git a/packages/techdocs-cli/cypress/support/e2e.js b/packages/techdocs-cli/cypress/support/e2e.js deleted file mode 100644 index f06a08e9a5..0000000000 --- a/packages/techdocs-cli/cypress/support/e2e.js +++ /dev/null @@ -1,36 +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. - */ - -// This example support/index.js is processed and -// loaded automatically before your test files. -// -// This is a great place to put global configuration and -// behavior that modifies Cypress. -// -// You can change the location of this file or turn off -// automatically serving support files with the -// 'supportFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/configuration -// *********************************************************** - -// Import commands.js using ES2015 syntax: -import './commands'; -import '@frsource/cypress-plugin-visual-regression-diff/commands'; - -// Alternatively you can use CommonJS syntax: -// require('./commands') diff --git a/packages/techdocs-cli/package.json b/packages/techdocs-cli/package.json index 9a8c420ffd..a82ec104f2 100644 --- a/packages/techdocs-cli/package.json +++ b/packages/techdocs-cli/package.json @@ -29,7 +29,6 @@ "test": "backstage-cli package test", "test:e2e": "backstage-cli test --config e2e-test.config.js", "test:e2e:ci": "backstage-cli test --config e2e-test.config.js --watchAll=false --ci", - "test:cypress": "cypress open", "prepack": "./scripts/prepack.sh" }, "bin": { @@ -37,14 +36,12 @@ }, "devDependencies": { "@backstage/cli": "workspace:^", - "@frsource/cypress-plugin-visual-regression-diff": "^3.2.8", "@types/commander": "^2.12.2", "@types/fs-extra": "^9.0.6", "@types/http-proxy": "^1.17.4", "@types/node": "^18.17.8", "@types/serve-handler": "^6.1.0", "@types/webpack-env": "^1.15.3", - "cypress": "^10.0.0", "find-process": "^1.4.5", "nodemon": "^3.0.1", "techdocs-cli-embedded-app": "link:../techdocs-cli-embedded-app", diff --git a/scripts/verify-lockfile-duplicates.js b/scripts/verify-lockfile-duplicates.js index a8d344b741..ddf99f4fd6 100644 --- a/scripts/verify-lockfile-duplicates.js +++ b/scripts/verify-lockfile-duplicates.js @@ -36,7 +36,7 @@ async function findLockFiles() { if (!files.length) { // List all lock files that are in the root or in an immediate subdirectory - files = ['yarn.lock', 'cypress/yarn.lock', 'microsite/yarn.lock']; + files = ['yarn.lock', 'microsite/yarn.lock']; } return files.map(file => ({ diff --git a/yarn.lock b/yarn.lock index c70add6790..79a134018b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3305,7 +3305,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.13, @babel/runtime@npm:^7.20.6, @babel/runtime@npm:^7.20.7, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.22.15, @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.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.6, @babel/runtime@npm:^7.20.7, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.22.15, @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.22.15 resolution: "@babel/runtime@npm:7.22.15" dependencies: @@ -10222,42 +10222,6 @@ __metadata: languageName: node linkType: hard -"@cypress/request@npm:2.88.12, @cypress/request@npm:^2.88.10": - version: 2.88.12 - resolution: "@cypress/request@npm:2.88.12" - dependencies: - aws-sign2: ~0.7.0 - aws4: ^1.8.0 - caseless: ~0.12.0 - combined-stream: ~1.0.6 - extend: ~3.0.2 - forever-agent: ~0.6.1 - form-data: ~2.3.2 - http-signature: ~1.3.6 - is-typedarray: ~1.0.0 - isstream: ~0.1.2 - json-stringify-safe: ~5.0.1 - mime-types: ~2.1.19 - performance-now: ^2.1.0 - qs: ~6.10.3 - safe-buffer: ^5.1.2 - tough-cookie: ^4.1.3 - tunnel-agent: ^0.6.0 - uuid: ^8.3.2 - checksum: 2c6fbf7f3127d41bffca8374beaa8cf95450495a8a077b00309ea9d94dd2a4da450a77fe038e8ad26c97cdd7c39b65c53c850f8338ce9bc2dbe23ce2e2b48329 - languageName: node - linkType: hard - -"@cypress/xvfb@npm:^1.2.4": - version: 1.2.4 - resolution: "@cypress/xvfb@npm:1.2.4" - dependencies: - debug: ^3.1.0 - lodash.once: ^4.1.1 - checksum: 7bdcdaeb1bb692ec9d9bf8ec52538aa0bead6764753f4a067a171a511807a43fab016f7285a56bef6a606c2467ff3f1365e1ad2d2d583b81beed849ee1573fd1 - languageName: node - linkType: hard - "@dabh/diagnostics@npm:^2.0.2": version: 2.0.2 resolution: "@dabh/diagnostics@npm:2.0.2" @@ -10998,30 +10962,6 @@ __metadata: languageName: node linkType: hard -"@frsource/base64@npm:1.0.17": - version: 1.0.17 - resolution: "@frsource/base64@npm:1.0.17" - checksum: a01689ef785516ff0b7460f55792685fc782f8507518768396acb9283270d50a8149774f3acd5fa690ccd5a48b5ec4ace90a491458ffdd9e9f591c6b23eb5da5 - languageName: node - linkType: hard - -"@frsource/cypress-plugin-visual-regression-diff@npm:^3.2.8": - version: 3.3.10 - resolution: "@frsource/cypress-plugin-visual-regression-diff@npm:3.3.10" - dependencies: - "@frsource/base64": 1.0.17 - glob: 8.1.0 - meta-png: 1.0.6 - move-file: 2.1.0 - pixelmatch: 5.3.0 - pngjs: 7.0.0 - sharp: 0.32.1 - peerDependencies: - cypress: ">=4.5.0" - checksum: 879954ecba8829fd870379a1f4150a511fceab4c5a5c3df8abbab54e655e6560d52d925109364ea7f2d3484467ed5e9c3e4cfaf0058c12bbfbfc21d76ed79b40 - languageName: node - linkType: hard - "@gar/promisify@npm:^1.0.1, @gar/promisify@npm:^1.1.3": version: 1.1.3 resolution: "@gar/promisify@npm:1.1.3" @@ -11965,22 +11905,6 @@ __metadata: languageName: node linkType: hard -"@hapi/hoek@npm:^9.0.0": - version: 9.0.4 - resolution: "@hapi/hoek@npm:9.0.4" - checksum: a5503ebaad5407e0c99d0656b0bbc3e9ccac9eddc9b9f66e0358a2da9a9dd173c63c9f7c5e46504a05e1fc41d853e9a19617e258d4fcbe1a4be7f9e61da83920 - languageName: node - linkType: hard - -"@hapi/topo@npm:^5.0.0": - version: 5.0.0 - resolution: "@hapi/topo@npm:5.0.0" - dependencies: - "@hapi/hoek": ^9.0.0 - checksum: 8aa81f71696f88d7daeab4547e120e43c6ab78081a4f215eec5103dd858f3122a703512cdacc43aa7e27d99607345165acfeb2ee69e556e63afd50c5c57a36c3 - languageName: node - linkType: hard - "@humanwhocodes/config-array@npm:^0.11.11": version: 0.11.11 resolution: "@humanwhocodes/config-array@npm:0.11.11" @@ -14792,29 +14716,6 @@ __metadata: languageName: node linkType: hard -"@sideway/address@npm:^4.1.3": - version: 4.1.4 - resolution: "@sideway/address@npm:4.1.4" - dependencies: - "@hapi/hoek": ^9.0.0 - checksum: b9fca2a93ac2c975ba12e0a6d97853832fb1f4fb02393015e012b47fa916a75ca95102d77214b2a29a2784740df2407951af8c5dde054824c65577fd293c4cdb - languageName: node - linkType: hard - -"@sideway/formula@npm:^3.0.0": - version: 3.0.1 - resolution: "@sideway/formula@npm:3.0.1" - checksum: e4beeebc9dbe2ff4ef0def15cec0165e00d1612e3d7cea0bc9ce5175c3263fc2c818b679bd558957f49400ee7be9d4e5ac90487e1625b4932e15c4aa7919c57a - languageName: node - linkType: hard - -"@sideway/pinpoint@npm:^2.0.0": - version: 2.0.0 - resolution: "@sideway/pinpoint@npm:2.0.0" - checksum: 0f4491e5897fcf5bf02c46f5c359c56a314e90ba243f42f0c100437935daa2488f20482f0f77186bd6bf43345095a95d8143ecf8b1f4d876a7bc0806aba9c3d2 - languageName: node - linkType: hard - "@sinclair/typebox@npm:^0.24.1": version: 0.24.42 resolution: "@sinclair/typebox@npm:0.24.42" @@ -16478,7 +16379,6 @@ __metadata: "@backstage/cli-common": "workspace:^" "@backstage/config": "workspace:^" "@backstage/plugin-techdocs-node": "workspace:^" - "@frsource/cypress-plugin-visual-regression-diff": ^3.2.8 "@types/commander": ^2.12.2 "@types/dockerode": ^3.3.0 "@types/fs-extra": ^9.0.6 @@ -16487,7 +16387,6 @@ __metadata: "@types/serve-handler": ^6.1.0 "@types/webpack-env": ^1.15.3 commander: ^9.1.0 - cypress: ^10.0.0 dockerode: ^3.3.1 find-process: ^1.4.5 fs-extra: ^10.0.1 @@ -16504,19 +16403,7 @@ __metadata: languageName: unknown linkType: soft -"@testing-library/cypress@npm:^9.0.0": - version: 9.0.0 - resolution: "@testing-library/cypress@npm:9.0.0" - dependencies: - "@babel/runtime": ^7.14.6 - "@testing-library/dom": ^8.1.0 - peerDependencies: - cypress: ^12.0.0 - checksum: fbd24e8f0b8a60279b336de5f6bc0e7ad6fb31316eacab5128dacc7fccde1eb40935b90f2c3bddc7d814115fe3965c6dbf011785448cd15b5a5b0bc40ef5bb4c - languageName: node - linkType: hard - -"@testing-library/dom@npm:^8.0.0, @testing-library/dom@npm:^8.1.0": +"@testing-library/dom@npm:^8.0.0": version: 8.20.1 resolution: "@testing-library/dom@npm:8.20.1" dependencies: @@ -17779,13 +17666,6 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^14.14.31": - version: 14.18.62 - resolution: "@types/node@npm:14.18.62" - checksum: 1335b4d58d2a21c7f60b8b78d0902ec0653a44f1ead4e921c37dd5f836910e0b00370abfde02c57bc3a73a35ebcbf4ef86b598be9a9ec13981a9a6d40e98fab0 - languageName: node - linkType: hard - "@types/node@npm:^15.6.1": version: 15.14.9 resolution: "@types/node@npm:15.14.9" @@ -17793,7 +17673,7 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^16.18.39, @types/node@npm:^16.9.2": +"@types/node@npm:^16.9.2": version: 16.18.53 resolution: "@types/node@npm:16.18.53" checksum: 26c05cde59664360c22e0dda70776ca6f1b35f0b94e4f84d2c21e2afa2e69ac3a2c99bbb57b43405f81df1b2598f6d707ccc7c4c31865f90e45c4625d8400518 @@ -18303,14 +18183,7 @@ __metadata: languageName: node linkType: hard -"@types/sinonjs__fake-timers@npm:8.1.1": - version: 8.1.1 - resolution: "@types/sinonjs__fake-timers@npm:8.1.1" - checksum: ca09d54d47091d87020824a73f026300fa06b17cd9f2f9b9387f28b549364b141ef194ee28db762f6588de71d8febcd17f753163cb7ea116b8387c18e80ebd5c - languageName: node - linkType: hard - -"@types/sizzle@npm:*, @types/sizzle@npm:^2.3.2": +"@types/sizzle@npm:*": version: 2.3.2 resolution: "@types/sizzle@npm:2.3.2" checksum: 783b6382934d8f12f2e21220a01c4557150f07abd18336f392664fb74ceaa9a9d59b7c859c0b82fd3f15b6484774cd0d493261fe64c78ee399bf198a8fe8d89d @@ -19565,13 +19438,6 @@ __metadata: languageName: node linkType: hard -"arch@npm:^2.2.0": - version: 2.2.0 - resolution: "arch@npm:2.2.0" - checksum: e21b7635029fe8e9cdd5a026f9a6c659103e63fff423834323cdf836a1bb240a72d0c39ca8c470f84643385cf581bd8eda2cad8bf493e27e54bd9783abe9101f - languageName: node - linkType: hard - "archiver-utils@npm:^2.1.0": version: 2.1.0 resolution: "archiver-utils@npm:2.1.0" @@ -19632,13 +19498,6 @@ __metadata: languageName: node linkType: hard -"arg@npm:^5.0.2": - version: 5.0.2 - resolution: "arg@npm:5.0.2" - checksum: 6c69ada1a9943d332d9e5382393e897c500908d91d5cb735a01120d5f71daf1b339b7b8980cbeaba8fd1afc68e658a739746179e4315a26e8a28951ff9930078 - languageName: node - linkType: hard - "argparse@npm:^1.0.10, argparse@npm:^1.0.7, argparse@npm:~1.0.9": version: 1.0.10 resolution: "argparse@npm:1.0.10" @@ -20553,14 +20412,7 @@ __metadata: languageName: node linkType: hard -"blob-util@npm:^2.0.2": - version: 2.0.2 - resolution: "blob-util@npm:2.0.2" - checksum: d543e6b92e4ca715ca33c78e89a07a2290d43e5b2bc897d7ec588c5c7bbf59df93e45225ac0c9258aa6ce4320358990f99c9288f1c48280f8ec5d7a2e088d19b - languageName: node - linkType: hard - -"bluebird@npm:3.7.2, bluebird@npm:^3.5.5, bluebird@npm:^3.7.2": +"bluebird@npm:^3.5.5, bluebird@npm:^3.7.2": version: 3.7.2 resolution: "bluebird@npm:3.7.2" checksum: 869417503c722e7dc54ca46715f70e15f4d9c602a423a02c825570862d12935be59ed9c7ba34a9b31f186c017c23cac6b54e35446f8353059c101da73eac22ef @@ -20885,7 +20737,7 @@ __metadata: languageName: node linkType: hard -"buffer@npm:^5.2.1, buffer@npm:^5.5.0, buffer@npm:^5.6.0": +"buffer@npm:^5.2.1, buffer@npm:^5.5.0": version: 5.7.1 resolution: "buffer@npm:5.7.1" dependencies: @@ -21050,13 +20902,6 @@ __metadata: languageName: node linkType: hard -"cachedir@npm:^2.3.0": - version: 2.3.0 - resolution: "cachedir@npm:2.3.0" - checksum: ec90cb0f2e6336e266aa748dbadf3da9e0b20e843e43f1591acab7a3f1451337dc2f26cb9dd833ae8cfefeffeeb43ef5b5ff62782a685f4e3c2305dd98482fcb - languageName: node - linkType: hard - "call-bind@npm:^1.0.0, call-bind@npm:^1.0.2": version: 1.0.2 resolution: "call-bind@npm:1.0.2" @@ -21343,13 +21188,6 @@ __metadata: languageName: node linkType: hard -"check-more-types@npm:2.24.0, check-more-types@npm:^2.24.0": - version: 2.24.0 - resolution: "check-more-types@npm:2.24.0" - checksum: b09080ec3404d20a4b0ead828994b2e5913236ef44ed3033a27062af0004cf7d2091fbde4b396bf13b7ce02fb018bc9960b48305e6ab2304cd82d73ed7a51ef4 - languageName: node - linkType: hard - "check-types@npm:^11.1.1": version: 11.1.2 resolution: "check-types@npm:11.1.2" @@ -21496,19 +21334,6 @@ __metadata: languageName: node linkType: hard -"cli-table3@npm:~0.6.1": - version: 0.6.1 - resolution: "cli-table3@npm:0.6.1" - dependencies: - colors: 1.4.0 - string-width: ^4.2.0 - dependenciesMeta: - colors: - optional: true - checksum: 956e175f8eb019c26465b9f1e51121c08d8978e2aab04be7f8520ea8a4e67906fcbd8516dfb77e386ae3730ef0281aa21a65613dffbfa3d62969263252bd25a9 - languageName: node - linkType: hard - "cli-table@npm:^0.3.1": version: 0.3.6 resolution: "cli-table@npm:0.3.6" @@ -21828,7 +21653,7 @@ __metadata: languageName: node linkType: hard -"color@npm:^4.0.1, color@npm:^4.2.3": +"color@npm:^4.0.1": version: 4.2.3 resolution: "color@npm:4.2.3" dependencies: @@ -21866,13 +21691,6 @@ __metadata: languageName: node linkType: hard -"colors@npm:1.4.0": - version: 1.4.0 - resolution: "colors@npm:1.4.0" - checksum: 98aa2c2418ad87dedf25d781be69dc5fc5908e279d9d30c34d8b702e586a0474605b3a189511482b9d5ed0d20c867515d22749537f7bc546256c6014f3ebdcec - languageName: node - linkType: hard - "colors@npm:~1.2.1": version: 1.2.5 resolution: "colors@npm:1.2.5" @@ -21969,13 +21787,6 @@ __metadata: languageName: node linkType: hard -"commander@npm:^6.2.1": - version: 6.2.1 - resolution: "commander@npm:6.2.1" - checksum: d7090410c0de6bc5c67d3ca41c41760d6d268f3c799e530aafb73b7437d1826bbf0d2a3edac33f8b57cc9887b4a986dce307fa5557e109be40eadb7c43b21742 - languageName: node - linkType: hard - "commander@npm:^7.2.0": version: 7.2.0 resolution: "commander@npm:7.2.0" @@ -22004,7 +21815,7 @@ __metadata: languageName: node linkType: hard -"common-tags@npm:1.8.2, common-tags@npm:^1.8.0": +"common-tags@npm:1.8.2": version: 1.8.2 resolution: "common-tags@npm:1.8.2" checksum: 767a6255a84bbc47df49a60ab583053bb29a7d9687066a18500a516188a062c4e4cd52de341f22de0b07062e699b1b8fe3cfa1cb55b241cb9301aeb4f45b4dff @@ -22942,111 +22753,6 @@ __metadata: languageName: node linkType: hard -"cypress@npm:^10.0.0": - version: 10.11.0 - resolution: "cypress@npm:10.11.0" - dependencies: - "@cypress/request": ^2.88.10 - "@cypress/xvfb": ^1.2.4 - "@types/node": ^14.14.31 - "@types/sinonjs__fake-timers": 8.1.1 - "@types/sizzle": ^2.3.2 - arch: ^2.2.0 - blob-util: ^2.0.2 - bluebird: ^3.7.2 - buffer: ^5.6.0 - cachedir: ^2.3.0 - chalk: ^4.1.0 - check-more-types: ^2.24.0 - cli-cursor: ^3.1.0 - cli-table3: ~0.6.1 - commander: ^5.1.0 - common-tags: ^1.8.0 - dayjs: ^1.10.4 - debug: ^4.3.2 - enquirer: ^2.3.6 - eventemitter2: 6.4.7 - execa: 4.1.0 - executable: ^4.1.1 - extract-zip: 2.0.1 - figures: ^3.2.0 - fs-extra: ^9.1.0 - getos: ^3.2.1 - is-ci: ^3.0.0 - is-installed-globally: ~0.4.0 - lazy-ass: ^1.6.0 - listr2: ^3.8.3 - lodash: ^4.17.21 - log-symbols: ^4.0.0 - minimist: ^1.2.6 - ospath: ^1.2.2 - pretty-bytes: ^5.6.0 - proxy-from-env: 1.0.0 - request-progress: ^3.0.0 - semver: ^7.3.2 - supports-color: ^8.1.1 - tmp: ~0.2.1 - untildify: ^4.0.0 - yauzl: ^2.10.0 - bin: - cypress: bin/cypress - checksum: 938cc6a20f7eeace5c8e850d234904ee1651cbb36d94666fe600cf17ce964e73d4f7d8d944aab677491702a57364e6aceeb4fe8bcbd96147ff5e2b575a956fb2 - languageName: node - linkType: hard - -"cypress@npm:^12.0.0": - version: 12.17.4 - resolution: "cypress@npm:12.17.4" - dependencies: - "@cypress/request": 2.88.12 - "@cypress/xvfb": ^1.2.4 - "@types/node": ^16.18.39 - "@types/sinonjs__fake-timers": 8.1.1 - "@types/sizzle": ^2.3.2 - arch: ^2.2.0 - blob-util: ^2.0.2 - bluebird: ^3.7.2 - buffer: ^5.6.0 - cachedir: ^2.3.0 - chalk: ^4.1.0 - check-more-types: ^2.24.0 - cli-cursor: ^3.1.0 - cli-table3: ~0.6.1 - commander: ^6.2.1 - common-tags: ^1.8.0 - dayjs: ^1.10.4 - debug: ^4.3.4 - enquirer: ^2.3.6 - eventemitter2: 6.4.7 - execa: 4.1.0 - executable: ^4.1.1 - extract-zip: 2.0.1 - figures: ^3.2.0 - fs-extra: ^9.1.0 - getos: ^3.2.1 - is-ci: ^3.0.0 - is-installed-globally: ~0.4.0 - lazy-ass: ^1.6.0 - listr2: ^3.8.3 - lodash: ^4.17.21 - log-symbols: ^4.0.0 - minimist: ^1.2.8 - ospath: ^1.2.2 - pretty-bytes: ^5.6.0 - process: ^0.11.10 - proxy-from-env: 1.0.0 - request-progress: ^3.0.0 - semver: ^7.5.3 - supports-color: ^8.1.1 - tmp: ~0.2.1 - untildify: ^4.0.0 - yauzl: ^2.10.0 - bin: - cypress: bin/cypress - checksum: c9c79f5493b23e9c8cfb92d45d50ea9d0fae54210dde203bfa794a79436faf60108d826fe9007a7d67fddf7919802ad8f006b7ae56c5c198c75d5bc85bbc851b - languageName: node - linkType: hard - "d3-array@npm:2 - 3, d3-array@npm:2.10.0 - 3, d3-array@npm:^3.1.6": version: 3.2.3 resolution: "d3-array@npm:3.2.3" @@ -23295,13 +23001,6 @@ __metadata: languageName: node linkType: hard -"dayjs@npm:^1.10.4": - version: 1.10.4 - resolution: "dayjs@npm:1.10.4" - checksum: d248d6aa1e04f8577a94978e5194c1023347bc08b7c2766d4a4d50b0b69382d3f4fd912b9fcb64ffad4ee2947d53cd8e5d707f49b14817eb7810959d8d95c938 - languageName: node - linkType: hard - "debounce@npm:^1.1.0, debounce@npm:^1.2.0": version: 1.2.1 resolution: "debounce@npm:1.2.1" @@ -23330,7 +23029,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:^3.1.0, debug@npm:^3.2.7": +"debug@npm:^3.2.7": version: 3.2.7 resolution: "debug@npm:3.2.7" dependencies: @@ -23623,7 +23322,7 @@ __metadata: languageName: node linkType: hard -"detect-libc@npm:^2.0.0, detect-libc@npm:^2.0.1": +"detect-libc@npm:^2.0.0": version: 2.0.1 resolution: "detect-libc@npm:2.0.1" checksum: ccb05fcabbb555beb544d48080179c18523a343face9ee4e1a86605a8715b4169f94d663c21a03c310ac824592f2ba9a5270218819bb411ad7be578a527593d7 @@ -23985,7 +23684,7 @@ __metadata: languageName: node linkType: hard -"duplexer@npm:^0.1.2, duplexer@npm:~0.1.1": +"duplexer@npm:^0.1.2": version: 0.1.2 resolution: "duplexer@npm:0.1.2" checksum: 62ba61a830c56801db28ff6305c7d289b6dc9f859054e8c982abd8ee0b0a14d2e9a8e7d086ffee12e868d43e2bbe8a964be55ddbd8c8957714c87373c7a4f9b0 @@ -24204,7 +23903,7 @@ __metadata: languageName: node linkType: hard -"enquirer@npm:^2.3.0, enquirer@npm:^2.3.6": +"enquirer@npm:^2.3.0": version: 2.3.6 resolution: "enquirer@npm:2.3.6" dependencies: @@ -24963,17 +24662,6 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-cypress@npm:^2.10.3": - version: 2.14.0 - resolution: "eslint-plugin-cypress@npm:2.14.0" - dependencies: - globals: ^13.20.0 - peerDependencies: - eslint: ">= 3.2.1" - checksum: 3fa118a757aebb1aa6b419b2944744796aa4fa3cc1e2e19fa97777fd6792fba12b5ae117bf19bf7e7d9a1abdd48398cfba9ca6f2c62fd690a2108a9a02f3f2ae - languageName: node - linkType: hard - "eslint-plugin-deprecation@npm:^1.3.2": version: 1.5.0 resolution: "eslint-plugin-deprecation@npm:1.5.0" @@ -25335,21 +25023,6 @@ __metadata: languageName: node linkType: hard -"event-stream@npm:=3.3.4": - version: 3.3.4 - resolution: "event-stream@npm:3.3.4" - dependencies: - duplexer: ~0.1.1 - from: ~0 - map-stream: ~0.1.0 - pause-stream: 0.0.11 - split: 0.3 - stream-combiner: ~0.0.4 - through: ~2.3.1 - checksum: 80b467820b6daf824d9fb4345d2daf115a056e5c104463f2e98534e92d196a27f2df5ea2aa085624db26f4c45698905499e881d13bc7c01f7a13eac85be72a22 - languageName: node - linkType: hard - "event-target-polyfill@npm:^0.0.3": version: 0.0.3 resolution: "event-target-polyfill@npm:0.0.3" @@ -25364,7 +25037,7 @@ __metadata: languageName: node linkType: hard -"eventemitter2@npm:6.4.7, eventemitter2@npm:^6.4.4": +"eventemitter2@npm:^6.4.4": version: 6.4.7 resolution: "eventemitter2@npm:6.4.7" checksum: 1b36a77e139d6965ebf3a36c01fa00c089ae6b80faa1911e52888f40b3a7057b36a2cc45dcd1ad87cda3798fe7b97a0aabcbb8175a8b96092a23bb7d0f039e66 @@ -25494,7 +25167,6 @@ __metadata: "@roadiehq/backstage-plugin-github-insights": ^2.0.5 "@roadiehq/backstage-plugin-github-pull-requests": ^2.2.7 "@roadiehq/backstage-plugin-travis-ci": ^2.0.5 - "@testing-library/cypress": ^9.0.0 "@testing-library/dom": ^8.0.0 "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 @@ -25505,8 +25177,6 @@ __metadata: "@types/zen-observable": ^0.8.0 app-next-example-plugin: "workspace:^" cross-env: ^7.0.0 - cypress: ^12.0.0 - eslint-plugin-cypress: ^2.10.3 history: ^5.0.0 lodash: ^4.17.21 prop-types: ^15.7.2 @@ -25515,7 +25185,6 @@ __metadata: react-router: ^6.3.0 react-router-dom: ^6.3.0 react-use: ^17.2.4 - start-server-and-test: ^1.10.11 zen-observable: ^0.10.0 languageName: unknown linkType: soft @@ -25610,7 +25279,6 @@ __metadata: "@roadiehq/backstage-plugin-github-insights": ^2.0.5 "@roadiehq/backstage-plugin-github-pull-requests": ^2.2.7 "@roadiehq/backstage-plugin-travis-ci": ^2.0.5 - "@testing-library/cypress": ^9.0.0 "@testing-library/dom": ^8.0.0 "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 @@ -25620,8 +25288,6 @@ __metadata: "@types/react-dom": "*" "@types/zen-observable": ^0.8.0 cross-env: ^7.0.0 - cypress: ^12.0.0 - eslint-plugin-cypress: ^2.10.3 history: ^5.0.0 prop-types: ^15.7.2 react: ^17.0.2 @@ -25629,7 +25295,6 @@ __metadata: react-router: ^6.3.0 react-router-dom: ^6.3.0 react-use: ^17.2.4 - start-server-and-test: ^1.10.11 zen-observable: ^0.10.0 languageName: unknown linkType: soft @@ -25753,40 +25418,6 @@ __metadata: languageName: unknown linkType: soft -"execa@npm:4.1.0": - version: 4.1.0 - resolution: "execa@npm:4.1.0" - dependencies: - cross-spawn: ^7.0.0 - get-stream: ^5.0.0 - human-signals: ^1.1.1 - is-stream: ^2.0.0 - merge-stream: ^2.0.0 - npm-run-path: ^4.0.0 - onetime: ^5.1.0 - signal-exit: ^3.0.2 - strip-final-newline: ^2.0.0 - checksum: e30d298934d9c52f90f3847704fd8224e849a081ab2b517bbc02f5f7732c24e56a21f14cb96a08256deffeb2d12b2b7cb7e2b014a12fb36f8d3357e06417ed55 - languageName: node - linkType: hard - -"execa@npm:5.1.1, execa@npm:^5.0.0": - version: 5.1.1 - resolution: "execa@npm:5.1.1" - dependencies: - cross-spawn: ^7.0.3 - get-stream: ^6.0.0 - human-signals: ^2.1.0 - is-stream: ^2.0.0 - merge-stream: ^2.0.0 - npm-run-path: ^4.0.1 - onetime: ^5.1.2 - signal-exit: ^3.0.3 - strip-final-newline: ^2.0.0 - checksum: fba9022c8c8c15ed862847e94c252b3d946036d7547af310e344a527e59021fd8b6bb0723883ea87044dc4f0201f949046993124a42ccb0855cae5bf8c786343 - languageName: node - linkType: hard - "execa@npm:7.2.0": version: 7.2.0 resolution: "execa@npm:7.2.0" @@ -25804,12 +25435,20 @@ __metadata: languageName: node linkType: hard -"executable@npm:^4.1.1": - version: 4.1.1 - resolution: "executable@npm:4.1.1" +"execa@npm:^5.0.0": + version: 5.1.1 + resolution: "execa@npm:5.1.1" dependencies: - pify: ^2.2.0 - checksum: f01927ce59bccec804e171bf859a26e362c1f50aa9ebc69f7cafdcce3859d29d4b6267fd47237c18b0a1830614bd3f0ee14b7380d9bad18a4e7af9b5f0b6984f + cross-spawn: ^7.0.3 + get-stream: ^6.0.0 + human-signals: ^2.1.0 + is-stream: ^2.0.0 + merge-stream: ^2.0.0 + npm-run-path: ^4.0.1 + onetime: ^5.1.2 + signal-exit: ^3.0.3 + strip-final-newline: ^2.0.0 + checksum: fba9022c8c8c15ed862847e94c252b3d946036d7547af310e344a527e59021fd8b6bb0723883ea87044dc4f0201f949046993124a42ccb0855cae5bf8c786343 languageName: node linkType: hard @@ -26300,7 +25939,7 @@ __metadata: languageName: node linkType: hard -"figures@npm:^3.0.0, figures@npm:^3.2.0": +"figures@npm:^3.0.0": version: 3.2.0 resolution: "figures@npm:3.2.0" dependencies: @@ -26738,13 +26377,6 @@ __metadata: languageName: node linkType: hard -"from@npm:~0": - version: 0.1.7 - resolution: "from@npm:0.1.7" - checksum: b85125b7890489656eb2e4f208f7654a93ec26e3aefaf3bbbcc0d496fc1941e4405834fcc9fe7333192aa2187905510ace70417bbf9ac6f6f4784a731d986939 - languageName: node - linkType: hard - "fromentries@npm:^1.3.1": version: 1.3.2 resolution: "fromentries@npm:1.3.2" @@ -26801,7 +26433,7 @@ __metadata: languageName: node linkType: hard -"fs-extra@npm:^9.0.0, fs-extra@npm:^9.1.0": +"fs-extra@npm:^9.0.0": version: 9.1.0 resolution: "fs-extra@npm:9.1.0" dependencies: @@ -27028,7 +26660,7 @@ __metadata: languageName: node linkType: hard -"get-stream@npm:^5.0.0, get-stream@npm:^5.1.0": +"get-stream@npm:^5.1.0": version: 5.1.0 resolution: "get-stream@npm:5.1.0" dependencies: @@ -27068,15 +26700,6 @@ __metadata: languageName: node linkType: hard -"getos@npm:^3.2.1": - version: 3.2.1 - resolution: "getos@npm:3.2.1" - dependencies: - async: ^3.2.0 - checksum: 42fd78a66d47cebd3e09de5566cc0044e034b08f4a000a310dbd89a77b02c65d8f4002554bfa495ea5bdc4fa9d515f5ac785a7cc474ba45383cc697f865eeaf1 - languageName: node - linkType: hard - "getpass@npm:^0.1.1": version: 0.1.7 resolution: "getpass@npm:0.1.7" @@ -27151,19 +26774,6 @@ __metadata: languageName: node linkType: hard -"glob@npm:8.1.0, glob@npm:^8.0.0, glob@npm:^8.0.1, glob@npm:^8.0.3": - version: 8.1.0 - resolution: "glob@npm:8.1.0" - dependencies: - fs.realpath: ^1.0.0 - inflight: ^1.0.4 - inherits: 2 - minimatch: ^5.0.1 - once: ^1.3.0 - checksum: 92fbea3221a7d12075f26f0227abac435de868dd0736a17170663783296d0dd8d3d532a5672b4488a439bf5d7fb85cdd07c11185d6cd39184f0385cbdfb86a47 - languageName: node - linkType: hard - "glob@npm:^10.2.2": version: 10.2.7 resolution: "glob@npm:10.2.7" @@ -27193,6 +26803,19 @@ __metadata: languageName: node linkType: hard +"glob@npm:^8.0.0, glob@npm:^8.0.1, glob@npm:^8.0.3": + version: 8.1.0 + resolution: "glob@npm:8.1.0" + dependencies: + fs.realpath: ^1.0.0 + inflight: ^1.0.4 + inherits: 2 + minimatch: ^5.0.1 + once: ^1.3.0 + checksum: 92fbea3221a7d12075f26f0227abac435de868dd0736a17170663783296d0dd8d3d532a5672b4488a439bf5d7fb85cdd07c11185d6cd39184f0385cbdfb86a47 + languageName: node + linkType: hard + "global-agent@npm:^3.0.0": version: 3.0.0 resolution: "global-agent@npm:3.0.0" @@ -27207,15 +26830,6 @@ __metadata: languageName: node linkType: hard -"global-dirs@npm:^3.0.0": - version: 3.0.0 - resolution: "global-dirs@npm:3.0.0" - dependencies: - ini: 2.0.0 - checksum: 953c17cf14bf6ee0e2100ae82a0d779934eed8a3ec5c94a7a4f37c5b3b592c31ea015fb9a15cf32484de13c79f4a814f3015152f3e1d65976cfbe47c1bfe4a88 - languageName: node - linkType: hard - "global-modules@npm:^2.0.0": version: 2.0.0 resolution: "global-modules@npm:2.0.0" @@ -27243,7 +26857,7 @@ __metadata: languageName: node linkType: hard -"globals@npm:^13.19.0, globals@npm:^13.20.0": +"globals@npm:^13.19.0": version: 13.20.0 resolution: "globals@npm:13.20.0" dependencies: @@ -28124,17 +27738,6 @@ __metadata: languageName: node linkType: hard -"http-signature@npm:~1.3.6": - version: 1.3.6 - resolution: "http-signature@npm:1.3.6" - dependencies: - assert-plus: ^1.0.0 - jsprim: ^2.0.2 - sshpk: ^1.14.1 - checksum: 10be2af4764e71fee0281392937050201ee576ac755c543f570d6d87134ce5e858663fe999a7adb3e4e368e1e356d0d7fec6b9542295b875726ff615188e7a0c - languageName: node - linkType: hard - "http2-wrapper@npm:^1.0.0-beta.5.2": version: 1.0.0-beta.5.2 resolution: "http2-wrapper@npm:1.0.0-beta.5.2" @@ -28169,13 +27772,6 @@ __metadata: languageName: node linkType: hard -"human-signals@npm:^1.1.1": - version: 1.1.1 - resolution: "human-signals@npm:1.1.1" - checksum: d587647c9e8ec24e02821b6be7de5a0fc37f591f6c4e319b3054b43fd4c35a70a94c46fc74d8c1a43c47fde157d23acd7421f375e1c1365b09a16835b8300205 - languageName: node - linkType: hard - "human-signals@npm:^2.1.0": version: 2.1.0 resolution: "human-signals@npm:2.1.0" @@ -28470,13 +28066,6 @@ __metadata: languageName: node linkType: hard -"ini@npm:2.0.0": - version: 2.0.0 - resolution: "ini@npm:2.0.0" - checksum: e7aadc5fb2e4aefc666d74ee2160c073995a4061556b1b5b4241ecb19ad609243b9cceafe91bae49c219519394bbd31512516cb22a3b1ca6e66d869e0447e84e - languageName: node - linkType: hard - "ini@npm:^1.3.5, ini@npm:~1.3.0": version: 1.3.8 resolution: "ini@npm:1.3.8" @@ -28781,7 +28370,7 @@ __metadata: languageName: node linkType: hard -"is-ci@npm:^3.0.0, is-ci@npm:^3.0.1": +"is-ci@npm:^3.0.1": version: 3.0.1 resolution: "is-ci@npm:3.0.1" dependencies: @@ -28909,16 +28498,6 @@ __metadata: languageName: node linkType: hard -"is-installed-globally@npm:~0.4.0": - version: 0.4.0 - resolution: "is-installed-globally@npm:0.4.0" - dependencies: - global-dirs: ^3.0.0 - is-path-inside: ^3.0.2 - checksum: 3359840d5982d22e9b350034237b2cda2a12bac1b48a721912e1ab8e0631dd07d45a2797a120b7b87552759a65ba03e819f1bd63f2d7ab8657ec0b44ee0bf399 - languageName: node - linkType: hard - "is-interactive@npm:^1.0.0": version: 1.0.0 resolution: "is-interactive@npm:1.0.0" @@ -29010,7 +28589,7 @@ __metadata: languageName: node linkType: hard -"is-path-inside@npm:^3.0.2, is-path-inside@npm:^3.0.3": +"is-path-inside@npm:^3.0.3": version: 3.0.3 resolution: "is-path-inside@npm:3.0.3" checksum: abd50f06186a052b349c15e55b182326f1936c89a78bf6c8f2b707412517c097ce04bc49a0ca221787bc44e1049f51f09a2ffb63d22899051988d3a618ba13e9 @@ -30175,19 +29754,6 @@ __metadata: languageName: node linkType: hard -"joi@npm:^17.7.0": - version: 17.7.0 - resolution: "joi@npm:17.7.0" - dependencies: - "@hapi/hoek": ^9.0.0 - "@hapi/topo": ^5.0.0 - "@sideway/address": ^4.1.3 - "@sideway/formula": ^3.0.0 - "@sideway/pinpoint": ^2.0.0 - checksum: 767a847936cb66787256c4351ff86e1b9e8d7383cbe81a5c827064032c2a8e8b6e938baef5ad32c4035fe4c56e537bd90aa2a952be8a0658601c920cdeb4fb3c - languageName: node - linkType: hard - "jose@npm:^4.14.4, jose@npm:^4.6.0": version: 4.14.6 resolution: "jose@npm:4.14.6" @@ -30783,18 +30349,6 @@ __metadata: languageName: node linkType: hard -"jsprim@npm:^2.0.2": - version: 2.0.2 - resolution: "jsprim@npm:2.0.2" - dependencies: - assert-plus: 1.0.0 - extsprintf: 1.3.0 - json-schema: 0.4.0 - verror: 1.10.0 - checksum: d175f6b1991e160cb0aa39bc857da780e035611986b5492f32395411879fdaf4e513d98677f08f7352dac93a16b66b8361c674b86a3fa406e2e7af6b26321838 - languageName: node - linkType: hard - "jss-camel-case@npm:^6.0.0": version: 6.1.0 resolution: "jss-camel-case@npm:6.1.0" @@ -31202,13 +30756,6 @@ __metadata: languageName: node linkType: hard -"lazy-ass@npm:1.6.0, lazy-ass@npm:^1.6.0": - version: 1.6.0 - resolution: "lazy-ass@npm:1.6.0" - checksum: 5a3ebb17915b03452320804466345382a6c25ac782ec4874fecdb2385793896cd459be2f187dc7def8899180c32ee0ab9a1aa7fe52193ac3ff3fe29bb0591729 - languageName: node - linkType: hard - "lazystream@npm:^1.0.0": version: 1.0.0 resolution: "lazystream@npm:1.0.0" @@ -31429,27 +30976,6 @@ __metadata: languageName: node linkType: hard -"listr2@npm:^3.8.3": - version: 3.14.0 - resolution: "listr2@npm:3.14.0" - dependencies: - cli-truncate: ^2.1.0 - colorette: ^2.0.16 - log-update: ^4.0.0 - p-map: ^4.0.0 - rfdc: ^1.3.0 - rxjs: ^7.5.1 - through: ^2.3.8 - wrap-ansi: ^7.0.0 - peerDependencies: - enquirer: ">= 2.3.0 < 3" - peerDependenciesMeta: - enquirer: - optional: true - checksum: fdb8b2d6bdf5df9371ebd5082bee46c6d0ca3d1e5f2b11fbb5a127839855d5f3da9d4968fce94f0a5ec67cac2459766abbb1faeef621065ebb1829b11ef9476d - languageName: node - linkType: hard - "listr2@npm:^4.0.5": version: 4.0.5 resolution: "listr2@npm:4.0.5" @@ -31722,13 +31248,6 @@ __metadata: languageName: node linkType: hard -"lodash.once@npm:^4.1.1": - version: 4.1.1 - resolution: "lodash.once@npm:4.1.1" - checksum: d768fa9f9b4e1dc6453be99b753906f58990e0c45e7b2ca5a3b40a33111e5d17f6edf2f768786e2716af90a8e78f8f91431ab8435f761fef00f9b0c256f6d245 - languageName: node - linkType: hard - "lodash.sortby@npm:^4.7.0": version: 4.7.0 resolution: "lodash.sortby@npm:4.7.0" @@ -32134,13 +31653,6 @@ __metadata: languageName: node linkType: hard -"map-stream@npm:~0.1.0": - version: 0.1.0 - resolution: "map-stream@npm:0.1.0" - checksum: 38abbe4eb883888031e6b2fc0630bc583c99396be16b8ace5794b937b682a8a081f03e8b15bfd4914d1bc88318f0e9ac73ba3512ae65955cd449f63256ddb31d - languageName: node - linkType: hard - "markdown-it-anchor@npm:^8.4.1": version: 8.6.4 resolution: "markdown-it-anchor@npm:8.6.4" @@ -32526,13 +32038,6 @@ __metadata: languageName: node linkType: hard -"meta-png@npm:1.0.6": - version: 1.0.6 - resolution: "meta-png@npm:1.0.6" - checksum: aed14b3b53189c9d32002d76c40926bd93dd9d439bae3ad23ffb2645c375c9772c160879aa8af59ac85a2f43ae8bbe06b9648a53fe27815f4aeab238f4e9b79d - languageName: node - linkType: hard - "methods@npm:^1.0.0, methods@npm:^1.1.2, methods@npm:~1.1.2": version: 1.1.2 resolution: "methods@npm:1.1.2" @@ -33081,7 +32586,7 @@ __metadata: languageName: node linkType: hard -"minimist@npm:>=1.2.2, minimist@npm:^1.2.0, minimist@npm:^1.2.3, minimist@npm:^1.2.5, minimist@npm:^1.2.6, minimist@npm:^1.2.7, minimist@npm:^1.2.8": +"minimist@npm:>=1.2.2, minimist@npm:^1.2.0, minimist@npm:^1.2.3, minimist@npm:^1.2.5, minimist@npm:^1.2.6": version: 1.2.8 resolution: "minimist@npm:1.2.8" checksum: 75a6d645fb122dad29c06a7597bddea977258957ed88d7a6df59b5cd3fe4a527e253e9bbf2e783e4b73657f9098b96a5fe96ab8a113655d4109108577ecf85b0 @@ -33330,15 +32835,6 @@ __metadata: languageName: node linkType: hard -"move-file@npm:2.1.0": - version: 2.1.0 - resolution: "move-file@npm:2.1.0" - dependencies: - path-exists: ^4.0.0 - checksum: 2b92bbe047a302b593fcb2c0bf1131bb090ec80b3264569fc80d782c8ff829eecc13573943fa4d804c9747dec612ef2d1e84a5cfcf29cbc64a69ffcbb7ea09b3 - languageName: node - linkType: hard - "mri@npm:1.1.4": version: 1.1.4 resolution: "mri@npm:1.1.4" @@ -33669,15 +33165,6 @@ __metadata: languageName: node linkType: hard -"node-addon-api@npm:^6.1.0": - version: 6.1.0 - resolution: "node-addon-api@npm:6.1.0" - dependencies: - node-gyp: latest - checksum: 3a539510e677cfa3a833aca5397300e36141aca064cdc487554f2017110709a03a95da937e98c2a14ec3c626af7b2d1b6dabe629a481f9883143d0d5bff07bf2 - languageName: node - linkType: hard - "node-cache@npm:^5.1.2": version: 5.1.2 resolution: "node-cache@npm:5.1.2" @@ -34065,7 +33552,7 @@ __metadata: languageName: node linkType: hard -"npm-run-path@npm:^4.0.0, npm-run-path@npm:^4.0.1": +"npm-run-path@npm:^4.0.1": version: 4.0.1 resolution: "npm-run-path@npm:4.0.1" dependencies: @@ -34522,13 +34009,6 @@ __metadata: languageName: node linkType: hard -"ospath@npm:^1.2.2": - version: 1.2.2 - resolution: "ospath@npm:1.2.2" - checksum: 505f48a4f4f1c557d6c656ec985707726e3714721680139be037613e903aa8c8fa4ddd8d1342006f9b2dc0065e6e20f8b7bea2ee05354f31257044790367b347 - languageName: node - linkType: hard - "outdent@npm:^0.5.0": version: 0.5.0 resolution: "outdent@npm:0.5.0" @@ -35227,15 +34707,6 @@ __metadata: languageName: node linkType: hard -"pause-stream@npm:0.0.11": - version: 0.0.11 - resolution: "pause-stream@npm:0.0.11" - dependencies: - through: ~2.3 - checksum: 3c4a14052a638b92e0c96eb00c0d7977df7f79ea28395250c525d197f1fc02d34ce1165d5362e2e6ebbb251524b94a76f3f0d4abc39ab8b016d97449fe15583c - languageName: node - linkType: hard - "pause@npm:0.0.1": version: 0.0.1 resolution: "pause@npm:0.0.1" @@ -35433,7 +34904,7 @@ __metadata: languageName: node linkType: hard -"pify@npm:^2.2.0, pify@npm:^2.3.0": +"pify@npm:^2.3.0": version: 2.3.0 resolution: "pify@npm:2.3.0" checksum: 9503aaeaf4577acc58642ad1d25c45c6d90288596238fb68f82811c08104c800e5a7870398e9f015d82b44ecbcbef3dc3d4251a1cbb582f6e5959fe09884b2ba @@ -35510,17 +34981,6 @@ __metadata: languageName: node linkType: hard -"pixelmatch@npm:5.3.0": - version: 5.3.0 - resolution: "pixelmatch@npm:5.3.0" - dependencies: - pngjs: ^6.0.0 - bin: - pixelmatch: bin/pixelmatch - checksum: f542713d89536551181ad9ddb666a1792ba00a8632d831093232a075cb3ccac05856e7a453ed7d0a41aaef64dcb5962e8ae5cbe646dd2761790d8ee51b0a0743 - languageName: node - linkType: hard - "pkg-dir@npm:^3.0.0": version: 3.0.0 resolution: "pkg-dir@npm:3.0.0" @@ -35593,20 +35053,6 @@ __metadata: languageName: node linkType: hard -"pngjs@npm:7.0.0": - version: 7.0.0 - resolution: "pngjs@npm:7.0.0" - checksum: b19a018930d27de26229c1b3ff250b3a25d09caa22cbb0b0459987d91eb0a560a18ab5d67da45a38ed7514140f26d1db58de83c31159ec101f2bb270a3c707f1 - languageName: node - linkType: hard - -"pngjs@npm:^6.0.0": - version: 6.0.0 - resolution: "pngjs@npm:6.0.0" - checksum: ab6c285086060087097eab9fe6b5a528a24f9e79c03dea2b4fd6264ed4fdb5beff4a3257eeeaf2a9dc18249b539609c2a4e4013c567164a1f6b5ba2c974d5ecb - languageName: node - linkType: hard - "pony-cause@npm:^1.0.0": version: 1.1.1 resolution: "pony-cause@npm:1.1.1" @@ -36178,7 +35624,7 @@ __metadata: languageName: node linkType: hard -"pretty-bytes@npm:^5.3.0, pretty-bytes@npm:^5.6.0": +"pretty-bytes@npm:^5.3.0": version: 5.6.0 resolution: "pretty-bytes@npm:5.6.0" checksum: 9c082500d1e93434b5b291bd651662936b8bd6204ec9fa17d563116a192d6d86b98f6d328526b4e8d783c07d5499e2614a807520249692da9ec81564b2f439cd @@ -36458,13 +35904,6 @@ __metadata: languageName: node linkType: hard -"proxy-from-env@npm:1.0.0": - version: 1.0.0 - resolution: "proxy-from-env@npm:1.0.0" - checksum: 292e28d1de0c315958d71d8315eb546dd3cd8c8cbc2dab7c54eeb9f5c17f421771964ad0b5e1f77011bab2305bdae42e1757ce33bdb1ccc3e87732322a8efcf1 - languageName: node - linkType: hard - "proxy-from-env@npm:1.1.0, proxy-from-env@npm:^1.1.0": version: 1.1.0 resolution: "proxy-from-env@npm:1.1.0" @@ -36472,17 +35911,6 @@ __metadata: languageName: node linkType: hard -"ps-tree@npm:1.2.0": - version: 1.2.0 - resolution: "ps-tree@npm:1.2.0" - dependencies: - event-stream: =3.3.4 - bin: - ps-tree: ./bin/ps-tree.js - checksum: e635dd00f53d30d31696cf5f95b3a8dbdf9b1aeb36d4391578ce8e8cd22949b7c5536c73b0dc18c78615ea3ddd4be96101166be59ca2e3e3cb1e2f79ba3c7f98 - languageName: node - linkType: hard - "pseudomap@npm:^1.0.2": version: 1.0.2 resolution: "pseudomap@npm:1.0.2" @@ -36616,15 +36044,6 @@ __metadata: languageName: node linkType: hard -"qs@npm:~6.10.3": - version: 6.10.4 - resolution: "qs@npm:6.10.4" - dependencies: - side-channel: ^1.0.4 - checksum: 31e4fedd759d01eae52dde6692abab175f9af3e639993c5caaa513a2a3607b34d8058d3ae52ceeccf37c3025f22ed5e90e9ddd6c2537e19c0562ddd10dc5b1eb - languageName: node - linkType: hard - "qs@npm:~6.5.2": version: 6.5.3 resolution: "qs@npm:6.5.3" @@ -38076,15 +37495,6 @@ __metadata: languageName: node linkType: hard -"request-progress@npm:^3.0.0": - version: 3.0.0 - resolution: "request-progress@npm:3.0.0" - dependencies: - throttleit: ^1.0.0 - checksum: 6ea1761dcc8a8b7b5894afd478c0286aa31bd69438d7050294bd4fd0d0b3e09b5cde417d38deef9c49809039c337d8744e4bb49d8632b0c3e4ffa5e8a687e0fd - languageName: node - linkType: hard - "request@npm:^2.88.0": version: 2.88.2 resolution: "request@npm:2.88.2" @@ -38673,7 +38083,7 @@ __metadata: languageName: node linkType: hard -"rxjs@npm:^7.2.0, rxjs@npm:^7.5.1, rxjs@npm:^7.5.5, rxjs@npm:^7.8.0, rxjs@npm:^7.8.1": +"rxjs@npm:^7.2.0, rxjs@npm:^7.5.5, rxjs@npm:^7.8.1": version: 7.8.1 resolution: "rxjs@npm:7.8.1" dependencies: @@ -38936,7 +38346,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.1.1, semver@npm:^7.1.2, semver@npm:^7.1.3, semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.0, semver@npm:^7.5.3, semver@npm:~7.5.4": +"semver@npm:^7.1.1, semver@npm:^7.1.2, semver@npm:^7.1.3, semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.3, semver@npm:~7.5.4": version: 7.5.4 resolution: "semver@npm:7.5.4" dependencies: @@ -39136,23 +38546,6 @@ __metadata: languageName: node linkType: hard -"sharp@npm:0.32.1": - version: 0.32.1 - resolution: "sharp@npm:0.32.1" - dependencies: - color: ^4.2.3 - detect-libc: ^2.0.1 - node-addon-api: ^6.1.0 - node-gyp: latest - prebuild-install: ^7.1.1 - semver: ^7.5.0 - simple-get: ^4.0.1 - tar-fs: ^2.1.1 - tunnel-agent: ^0.6.0 - checksum: 99f50df380442aa8f3f952dd6f2e27634f9cab249cce47aa7f1a97c468334979ea94d71555f782aae5f5016e44b7832799f1c5ea1cb3ca975c089acd00e62e2e - languageName: node - linkType: hard - "shebang-command@npm:^1.2.0": version: 1.2.0 resolution: "shebang-command@npm:1.2.0" @@ -39675,15 +39068,6 @@ __metadata: languageName: node linkType: hard -"split@npm:0.3": - version: 0.3.3 - resolution: "split@npm:0.3.3" - dependencies: - through: 2 - checksum: 2e076634c9637cfdc54ab4387b6a243b8c33b360874a25adf6f327a5647f07cb3bf1c755d515248eb3afee4e382278d01f62c62d87263c118f28065b86f74f02 - languageName: node - linkType: hard - "split@npm:^1.0.0": version: 1.0.1 resolution: "split@npm:1.0.1" @@ -39750,7 +39134,7 @@ __metadata: languageName: node linkType: hard -"sshpk@npm:^1.14.1, sshpk@npm:^1.7.0": +"sshpk@npm:^1.7.0": version: 1.16.1 resolution: "sshpk@npm:1.16.1" dependencies: @@ -39872,26 +39256,6 @@ __metadata: languageName: node linkType: hard -"start-server-and-test@npm:^1.10.11": - version: 1.15.4 - resolution: "start-server-and-test@npm:1.15.4" - dependencies: - arg: ^5.0.2 - bluebird: 3.7.2 - check-more-types: 2.24.0 - debug: 4.3.4 - execa: 5.1.1 - lazy-ass: 1.6.0 - ps-tree: 1.2.0 - wait-on: 7.0.1 - bin: - server-test: src/bin/start.js - start-server-and-test: src/bin/start.js - start-test: src/bin/start.js - checksum: 0df9a4710ea45ddb1a9f719e0865faa8e26a973beff693dfe244ae2d914bfc6eed4d2db8529cdcad3d53658c4655356e5aca3520485a3ef4d9d9f320956b0e7d - languageName: node - linkType: hard - "statuses@npm:2.0.1": version: 2.0.1 resolution: "statuses@npm:2.0.1" @@ -39940,15 +39304,6 @@ __metadata: languageName: node linkType: hard -"stream-combiner@npm:~0.0.4": - version: 0.0.4 - resolution: "stream-combiner@npm:0.0.4" - dependencies: - duplexer: ~0.1.1 - checksum: 844b622cfe8b9de45a6007404f613b60aaf85200ab9862299066204242f89a7c8033b1c356c998aa6cfc630f6cd9eba119ec1c6dc1f93e245982be4a847aee7d - languageName: node - linkType: hard - "stream-events@npm:^1.0.5": version: 1.0.5 resolution: "stream-events@npm:1.0.5" @@ -40708,14 +40063,11 @@ __metadata: "@types/react": "*" "@types/react-dom": "*" cross-env: ^7.0.0 - cypress: ^10.0.0 - eslint-plugin-cypress: ^2.10.3 history: ^5.0.0 react: ^17.0.2 react-dom: ^17.0.2 react-router-dom: ^6.3.0 react-use: ^17.2.4 - start-server-and-test: ^1.10.11 languageName: unknown linkType: soft @@ -40868,13 +40220,6 @@ __metadata: languageName: node linkType: hard -"throttleit@npm:^1.0.0": - version: 1.0.0 - resolution: "throttleit@npm:1.0.0" - checksum: 1b2db4d2454202d589e8236c07a69d2fab838876d370030ebea237c34c0a7d1d9cf11c29f994531ebb00efd31e9728291042b7754f2798a8352ec4463455b659 - languageName: node - linkType: hard - "through2@npm:^4.0.0": version: 4.0.2 resolution: "through2@npm:4.0.2" @@ -40884,7 +40229,7 @@ __metadata: languageName: node linkType: hard -"through@npm:2, through@npm:^2.3.6, through@npm:^2.3.8, through@npm:~2.3, through@npm:~2.3.1": +"through@npm:2, through@npm:^2.3.6, through@npm:^2.3.8": version: 2.3.8 resolution: "through@npm:2.3.8" checksum: a38c3e059853c494af95d50c072b83f8b676a9ba2818dcc5b108ef252230735c54e0185437618596c790bbba8fcdaef5b290405981ffa09dce67b1f1bf190cbd @@ -40976,7 +40321,7 @@ __metadata: languageName: node linkType: hard -"tmp@npm:^0.2.0, tmp@npm:^0.2.1, tmp@npm:~0.2.1": +"tmp@npm:^0.2.0, tmp@npm:^0.2.1": version: 0.2.1 resolution: "tmp@npm:0.2.1" dependencies: @@ -41064,7 +40409,7 @@ __metadata: languageName: node linkType: hard -"tough-cookie@npm:^4.0.0, tough-cookie@npm:^4.1.3": +"tough-cookie@npm:^4.0.0": version: 4.1.3 resolution: "tough-cookie@npm:4.1.3" dependencies: @@ -42473,21 +41818,6 @@ __metadata: languageName: node linkType: hard -"wait-on@npm:7.0.1": - version: 7.0.1 - resolution: "wait-on@npm:7.0.1" - dependencies: - axios: ^0.27.2 - joi: ^17.7.0 - lodash: ^4.17.21 - minimist: ^1.2.7 - rxjs: ^7.8.0 - bin: - wait-on: bin/wait-on - checksum: 1e8a17d8ee6436f71d3ab82781ce31267481fcd7bbccde49b0f8124871e6e40a1acac3401f04f775ba6203853a5813352fa131620fc139914351f3b2894d573f - languageName: node - linkType: hard - "walk-up-path@npm:^1.0.0": version: 1.0.0 resolution: "walk-up-path@npm:1.0.0" From 2b6e5720515cd7494ce7da4299405eef91ca00fd Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 25 Sep 2023 16:39:20 +0200 Subject: [PATCH 055/110] techdocs-cli: move e2e-tests to cli-e2e-tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Johan Haals Signed-off-by: Patrik Oldsberg --- .changeset/tiny-garlics-cheer.md | 5 +++++ .../{e2e-test.config.js => cli-e2e-test.config.js} | 2 +- .../{e2e-tests => cli-e2e-tests}/techdocs-cli.test.ts | 0 packages/techdocs-cli/package.json | 4 ++-- 4 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 .changeset/tiny-garlics-cheer.md rename packages/techdocs-cli/{e2e-test.config.js => cli-e2e-test.config.js} (93%) rename packages/techdocs-cli/{e2e-tests => cli-e2e-tests}/techdocs-cli.test.ts (100%) diff --git a/.changeset/tiny-garlics-cheer.md b/.changeset/tiny-garlics-cheer.md new file mode 100644 index 0000000000..992ed7f007 --- /dev/null +++ b/.changeset/tiny-garlics-cheer.md @@ -0,0 +1,5 @@ +--- +'@techdocs/cli': patch +--- + +Restructured tests. diff --git a/packages/techdocs-cli/e2e-test.config.js b/packages/techdocs-cli/cli-e2e-test.config.js similarity index 93% rename from packages/techdocs-cli/e2e-test.config.js rename to packages/techdocs-cli/cli-e2e-test.config.js index 2fa92462ab..b2e6e53918 100644 --- a/packages/techdocs-cli/e2e-test.config.js +++ b/packages/techdocs-cli/cli-e2e-test.config.js @@ -18,5 +18,5 @@ const path = require('path'); module.exports = require('@backstage/cli/config/jest').then(baseConfig => ({ ...baseConfig, - rootDir: path.resolve(__dirname, 'e2e-tests'), + rootDir: path.resolve(__dirname, 'cli-e2e-tests'), })); diff --git a/packages/techdocs-cli/e2e-tests/techdocs-cli.test.ts b/packages/techdocs-cli/cli-e2e-tests/techdocs-cli.test.ts similarity index 100% rename from packages/techdocs-cli/e2e-tests/techdocs-cli.test.ts rename to packages/techdocs-cli/cli-e2e-tests/techdocs-cli.test.ts diff --git a/packages/techdocs-cli/package.json b/packages/techdocs-cli/package.json index a82ec104f2..6883072c3b 100644 --- a/packages/techdocs-cli/package.json +++ b/packages/techdocs-cli/package.json @@ -27,8 +27,8 @@ "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", "test": "backstage-cli package test", - "test:e2e": "backstage-cli test --config e2e-test.config.js", - "test:e2e:ci": "backstage-cli test --config e2e-test.config.js --watchAll=false --ci", + "test:e2e": "backstage-cli test --config cli-e2e-test.config.js", + "test:e2e:ci": "backstage-cli test --config cli-e2e-test.config.js --watchAll=false --ci", "prepack": "./scripts/prepack.sh" }, "bin": { From 47280bccd948af0d48800bea810275127496804f Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 25 Sep 2023 16:40:40 +0200 Subject: [PATCH 056/110] add playright setup + migrate a few tests in example app MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Johan Haals Signed-off-by: Patrik Oldsberg --- .eslintignore | 1 + .gitignore | 3 + package.json | 3 + packages/app/e2e-tests/SearchPage.test.ts | 46 ++++++++++++++++ packages/app/e2e-tests/app.test.ts | 33 +++++++++++ packages/app/package.json | 1 + playwright.config.ts | 67 +++++++++++++++++++++++ 7 files changed, 154 insertions(+) create mode 100644 packages/app/e2e-tests/SearchPage.test.ts create mode 100644 packages/app/e2e-tests/app.test.ts create mode 100644 playwright.config.ts diff --git a/.eslintignore b/.eslintignore index 46bb1ad2b2..5ccd2d1ba0 100644 --- a/.eslintignore +++ b/.eslintignore @@ -9,3 +9,4 @@ **/microsite/** **/templates/** **/sample-templates/** +playwright.config.ts diff --git a/.gitignore b/.gitignore index 4ad888b46c..7149dbabc1 100644 --- a/.gitignore +++ b/.gitignore @@ -150,6 +150,9 @@ tsconfig.tmp.json # vscode database functionality support files *.session.sql +# E2E test reports +e2e-test-report/ + # Lighthouse CI Reports **/.lighthouseci/* !**/.lighthouseci/scripts diff --git a/package.json b/package.json index dcdd66f7c3..f027658ffd 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "clean": "backstage-cli repo clean", "test": "backstage-cli repo test", "test:all": "backstage-cli repo test --coverage", + "test:e2e": "playwright test", "fix": "backstage-cli repo fix", "lint": "backstage-cli repo lint --since origin/master", "lint:docs": "node ./scripts/check-docs-quality", @@ -58,9 +59,11 @@ "@backstage/cli": "workspace:*", "@backstage/codemods": "workspace:*", "@backstage/create-app": "workspace:*", + "@backstage/e2e-test-utils": "workspace:*", "@backstage/repo-tools": "workspace:*", "@changesets/cli": "^2.14.0", "@octokit/rest": "^19.0.3", + "@playwright/test": "^1.32.3", "@spotify/eslint-plugin": "^14.1.3", "@spotify/prettier-config": "^14.0.0", "@techdocs/cli": "workspace:*", diff --git a/packages/app/e2e-tests/SearchPage.test.ts b/packages/app/e2e-tests/SearchPage.test.ts new file mode 100644 index 0000000000..9c42cf3d0a --- /dev/null +++ b/packages/app/e2e-tests/SearchPage.test.ts @@ -0,0 +1,46 @@ +/* + * 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 { test, expect } from '@playwright/test'; + +test('the results are rendered as expected', async ({ page }) => { + await page.goto('/'); + + const enterButton = page.getByRole('button', { name: 'Enter' }); + await expect(enterButton).toBeVisible(); + await enterButton.click(); + + await page.goto('/search'); + await page.route(`http://*/api/search/query?term=*`, async route => { + const results = [ + { + type: 'software-catalog', + document: { + title: 'backstage', + text: 'Backstage system documentation', + location: '/result/location/path', + }, + }, + ]; + await route.fulfill({ json: { results } }); + }); + + await expect( + page.getByPlaceholder('Search in Backstage Example App'), + ).toBeVisible(); + + await expect(page.getByText('Backstage system documentation')).toBeVisible(); +}); diff --git a/packages/app/e2e-tests/app.test.ts b/packages/app/e2e-tests/app.test.ts new file mode 100644 index 0000000000..7449e4d9cb --- /dev/null +++ b/packages/app/e2e-tests/app.test.ts @@ -0,0 +1,33 @@ +/* + * Copyright 2020 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 { test, expect } from '@playwright/test'; + +test('App should render the welcome page', async ({ page }) => { + await page.goto('/'); + + const enterButton = page.getByRole('button', { name: 'Enter' }); + await expect(enterButton).toBeVisible(); + await enterButton.click(); + + await expect(page.getByText('My Company Catalog')).toBeVisible(); + + const supportButton = page.getByTestId('support-button'); + await expect(supportButton).toBeVisible(); + await supportButton.click(); + + await expect(page.getByText('#backstage')).toBeVisible(); +}); diff --git a/packages/app/package.json b/packages/app/package.json index d9aa5ee847..174db2c19b 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -103,6 +103,7 @@ }, "devDependencies": { "@backstage/test-utils": "workspace:^", + "@playwright/test": "^1.32.3", "@testing-library/dom": "^8.0.0", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", diff --git a/playwright.config.ts b/playwright.config.ts new file mode 100644 index 0000000000..ee8228e413 --- /dev/null +++ b/playwright.config.ts @@ -0,0 +1,67 @@ +/* + * 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 { defineConfig } from '@playwright/test'; +import { generateProjects } from '@backstage/e2e-test-utils/playwright'; + +/** + * See https://playwright.dev/docs/test-configuration. + */ +export default defineConfig({ + timeout: 30_000, + + expect: { + timeout: 5_000, + }, + + // Run your local dev server before starting the tests + webServer: process.env.CI + ? [] + : [ + { + command: 'yarn start', + port: 3000, + reuseExistingServer: true, + timeout: 60_000, + }, + // TODO: Before encouraging e2e tests for backend we'll want to provide better utilities for mocking auth + // { + // command: 'yarn start-backend', + // port: 7007, + // reuseExistingServer: true, + // timeout: 60_000, + // }, + ], + + forbidOnly: !!process.env.CI, + + retries: process.env.CI ? 2 : 0, + + reporter: [['html', { open: 'never', outputFolder: 'e2e-test-report' }]], + + use: { + actionTimeout: 0, + baseURL: + process.env.PLAYWRIGHT_URL ?? + (process.env.CI ? 'http://localhost:7007' : 'http://localhost:3000'), + screenshot: 'only-on-failure', + trace: 'on-first-retry', + }, + + outputDir: 'node_modules/.cache/e2e-test-results', + + projects: generateProjects(), // Find all packages with e2e-test folders +}); From 705a0dfe3f52e8129db5eafb12d1451224283f69 Mon Sep 17 00:00:00 2001 From: Anton Ganhammar Date: Mon, 25 Sep 2023 18:32:55 +0200 Subject: [PATCH 057/110] fix: remove history fix (to be moved to new pr) Signed-off-by: Anton Ganhammar --- .../components/CoverageHistoryChart/CoverageHistoryChart.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/code-coverage/src/components/CoverageHistoryChart/CoverageHistoryChart.tsx b/plugins/code-coverage/src/components/CoverageHistoryChart/CoverageHistoryChart.tsx index 09f499fafd..1e5341eb50 100644 --- a/plugins/code-coverage/src/components/CoverageHistoryChart/CoverageHistoryChart.tsx +++ b/plugins/code-coverage/src/components/CoverageHistoryChart/CoverageHistoryChart.tsx @@ -113,8 +113,8 @@ export const CoverageHistoryChart = () => { ); } - const [oldestCoverage] = valueHistory.history.slice(-1); - const latestCoverage = valueHistory.history[0]; + const oldestCoverage = valueHistory.history[0]; + const [latestCoverage] = valueHistory.history.slice(-1); const getTrendForCoverage = (type: Coverage) => { if (!oldestCoverage[type].percentage) { From 08f12abf006242b0c1cad484304f34efc5a3762d Mon Sep 17 00:00:00 2001 From: zcason Date: Mon, 25 Sep 2023 11:45:51 -0500 Subject: [PATCH 058/110] remove all graphql plugin migration work Signed-off-by: zcason --- .changeset/short-planets-suffer.md | 5 ---- packages/backend-next/package.json | 1 - packages/backend-next/src/index.ts | 1 - plugins/graphql-backend/README.md | 16 ---------- plugins/graphql-backend/api-report.md | 5 ---- plugins/graphql-backend/package.json | 1 - plugins/graphql-backend/src/index.ts | 1 - plugins/graphql-backend/src/plugin.ts | 42 --------------------------- yarn.lock | 2 -- 9 files changed, 74 deletions(-) delete mode 100644 .changeset/short-planets-suffer.md delete mode 100644 plugins/graphql-backend/src/plugin.ts diff --git a/.changeset/short-planets-suffer.md b/.changeset/short-planets-suffer.md deleted file mode 100644 index 9626a05e54..0000000000 --- a/.changeset/short-planets-suffer.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-graphql-backend': patch ---- - -Added support to the graphql plugin for the new backend diff --git a/packages/backend-next/package.json b/packages/backend-next/package.json index e7b52f7ad0..a6431aab06 100644 --- a/packages/backend-next/package.json +++ b/packages/backend-next/package.json @@ -38,7 +38,6 @@ "@backstage/plugin-catalog-backend-module-unprocessed": "workspace:^", "@backstage/plugin-devtools-backend": "workspace:^", "@backstage/plugin-entity-feedback-backend": "workspace:^", - "@backstage/plugin-graphql-backend": "workspace:^", "@backstage/plugin-kubernetes-backend": "workspace:^", "@backstage/plugin-lighthouse-backend": "workspace:^", "@backstage/plugin-linguist-backend": "workspace:^", diff --git a/packages/backend-next/src/index.ts b/packages/backend-next/src/index.ts index 68e33f4be3..04ddd838c8 100644 --- a/packages/backend-next/src/index.ts +++ b/packages/backend-next/src/index.ts @@ -29,7 +29,6 @@ backend.add( backend.add(import('@backstage/plugin-catalog-backend/alpha')); backend.add(import('@backstage/plugin-devtools-backend')); backend.add(import('@backstage/plugin-entity-feedback-backend')); -backend.add(import('@backstage/plugin-graphql-backend')); backend.add(import('@backstage/plugin-kubernetes-backend/alpha')); backend.add(import('@backstage/plugin-lighthouse-backend')); backend.add(import('@backstage/plugin-linguist-backend')); diff --git a/plugins/graphql-backend/README.md b/plugins/graphql-backend/README.md index d1bd53b38d..970222fb1f 100644 --- a/plugins/graphql-backend/README.md +++ b/plugins/graphql-backend/README.md @@ -26,19 +26,3 @@ yarn workspace example-backend start ``` This will launch the full example backend. - -### New Backend System - -The grahpql backend plugin has support for the [new backend system](https://backstage.io/docs/backend-system/), here's how you can set that up: -In your `packages/backend/src/index.ts` make the following changes: - -```diff -import { createBackend } from '@backstage/backend-defaults'; - -const backend = createBackend(); - -backend.add(import('@backstage/plugin-graphql-backend')); -// ... other feature additions - -backend.start(); -``` diff --git a/plugins/graphql-backend/api-report.md b/plugins/graphql-backend/api-report.md index 31cdf4c617..a787c4f209 100644 --- a/plugins/graphql-backend/api-report.md +++ b/plugins/graphql-backend/api-report.md @@ -3,7 +3,6 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { BackendFeature } from '@backstage/backend-plugin-api'; import { Config } from '@backstage/config'; import express from 'express'; import { Logger } from 'winston'; @@ -11,10 +10,6 @@ import { Logger } from 'winston'; // @public (undocumented) export function createRouter(options: RouterOptions): Promise; -// @public -const graphqlPlugin: () => BackendFeature; -export default graphqlPlugin; - // @public (undocumented) export interface RouterOptions { // (undocumented) diff --git a/plugins/graphql-backend/package.json b/plugins/graphql-backend/package.json index 2ed420983e..7582c150cb 100644 --- a/plugins/graphql-backend/package.json +++ b/plugins/graphql-backend/package.json @@ -35,7 +35,6 @@ "dependencies": { "@apollo/server": "^4.0.0", "@backstage/backend-common": "workspace:^", - "@backstage/backend-plugin-api": "workspace:^", "@backstage/config": "workspace:^", "@backstage/plugin-catalog-graphql": "workspace:^", "@graphql-tools/schema": "^9.0.0", diff --git a/plugins/graphql-backend/src/index.ts b/plugins/graphql-backend/src/index.ts index 5c21db501f..a9f7f92ad9 100644 --- a/plugins/graphql-backend/src/index.ts +++ b/plugins/graphql-backend/src/index.ts @@ -21,4 +21,3 @@ */ export * from './service/router'; -export { graphqlPlugin as default } from './plugin'; diff --git a/plugins/graphql-backend/src/plugin.ts b/plugins/graphql-backend/src/plugin.ts deleted file mode 100644 index 6401f87803..0000000000 --- a/plugins/graphql-backend/src/plugin.ts +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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 { - coreServices, - createBackendPlugin, -} from '@backstage/backend-plugin-api'; -import { createRouter } from './service/router'; -import { loggerToWinstonLogger } from '@backstage/backend-common'; - -export const graphqlPlugin = createBackendPlugin({ - pluginId: 'graphql', - register(env) { - env.registerInit({ - deps: { - config: coreServices.rootConfig, - http: coreServices.httpRouter, - logger: coreServices.logger, - }, - async init({ config, http, logger }) { - http.use( - await createRouter({ - config, - logger: loggerToWinstonLogger(logger), - }), - ); - }, - }); - }, -}); diff --git a/yarn.lock b/yarn.lock index 04215cd079..3f7ffd754b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7280,7 +7280,6 @@ __metadata: dependencies: "@apollo/server": ^4.0.0 "@backstage/backend-common": "workspace:^" - "@backstage/backend-plugin-api": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" "@backstage/plugin-catalog-graphql": "workspace:^" @@ -25962,7 +25961,6 @@ __metadata: "@backstage/plugin-catalog-backend-module-unprocessed": "workspace:^" "@backstage/plugin-devtools-backend": "workspace:^" "@backstage/plugin-entity-feedback-backend": "workspace:^" - "@backstage/plugin-graphql-backend": "workspace:^" "@backstage/plugin-kubernetes-backend": "workspace:^" "@backstage/plugin-lighthouse-backend": "workspace:^" "@backstage/plugin-linguist-backend": "workspace:^" From 0db06a69a1826d17534c3d67f09ed24765db502a Mon Sep 17 00:00:00 2001 From: zcason Date: Mon, 25 Sep 2023 12:17:28 -0500 Subject: [PATCH 059/110] updated api report Signed-off-by: zcason --- plugins/playlist-backend/api-report.md | 7 ++++--- plugins/playlist-backend/src/plugin.ts | 5 +++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/plugins/playlist-backend/api-report.md b/plugins/playlist-backend/api-report.md index 905b7bc5b1..40b05c25d4 100644 --- a/plugins/playlist-backend/api-report.md +++ b/plugins/playlist-backend/api-report.md @@ -32,9 +32,6 @@ export const createPlaylistConditionalDecision: ( // @public (undocumented) export function createRouter(options: RouterOptions): Promise; -// @public -export const playlistPlugin: () => BackendFeature; - // @public export class DefaultPlaylistPermissionPolicy implements PermissionPolicy { // (undocumented) @@ -84,6 +81,10 @@ export const playlistConditions: Conditions<{ >; }>; +// @public +const playlistPlugin: () => BackendFeature; +export default playlistPlugin; + // @public (undocumented) export interface RouterOptions { // (undocumented) diff --git a/plugins/playlist-backend/src/plugin.ts b/plugins/playlist-backend/src/plugin.ts index 12fe94b01a..b4d926c05e 100644 --- a/plugins/playlist-backend/src/plugin.ts +++ b/plugins/playlist-backend/src/plugin.ts @@ -20,6 +20,11 @@ import { import { createRouter } from './service'; import { loggerToWinstonLogger } from '@backstage/backend-common'; +/** + * Playlist backend plugin + * + * @public + */ export const playlistPlugin = createBackendPlugin({ pluginId: 'playlist', register(env) { From 911d90e306ca9006d3e902b3ec07966da6406dc9 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 25 Sep 2023 20:09:39 +0200 Subject: [PATCH 060/110] auth-node: avoid passing through empty scope in start Signed-off-by: Patrik Oldsberg --- plugins/auth-node/src/oauth/createOAuthRouteHandlers.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/auth-node/src/oauth/createOAuthRouteHandlers.ts b/plugins/auth-node/src/oauth/createOAuthRouteHandlers.ts index a455837035..165d7ce6b3 100644 --- a/plugins/auth-node/src/oauth/createOAuthRouteHandlers.ts +++ b/plugins/auth-node/src/oauth/createOAuthRouteHandlers.ts @@ -136,7 +136,7 @@ export function createOAuthRouteHandlers( // If scopes are persisted then we pass them through the state so that we // can set the cookie on successful auth - if (authenticator.shouldPersistScopes) { + if (authenticator.shouldPersistScopes && scope) { state.scope = scope; } From 5eacd5d213589dd516e874329d6aa5b9b426b828 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 25 Sep 2023 16:55:51 +0200 Subject: [PATCH 061/110] create-app: migrate to playwright MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Johan Haals Signed-off-by: Patrik Oldsberg --- .changeset/twelve-clouds-design.md | 9 +++ packages/create-app/src/lib/tasks.test.ts | 1 + packages/create-app/src/lib/versions.ts | 2 + .../templates/default-app/.gitignore.hbs | 3 + .../templates/default-app/package.json.hbs | 3 + .../packages/app/cypress.config.js | 11 ---- .../packages/app/cypress/.eslintrc.json | 12 ---- .../packages/app/cypress/e2e/app.cy.js | 6 -- .../packages/app/e2e-tests/app.test.ts | 23 +++++++ .../default-app/packages/app/package.json.hbs | 12 +--- .../default-app/playwright.config.ts | 60 +++++++++++++++++++ 11 files changed, 104 insertions(+), 38 deletions(-) create mode 100644 .changeset/twelve-clouds-design.md delete mode 100644 packages/create-app/templates/default-app/packages/app/cypress.config.js delete mode 100644 packages/create-app/templates/default-app/packages/app/cypress/.eslintrc.json delete mode 100644 packages/create-app/templates/default-app/packages/app/cypress/e2e/app.cy.js create mode 100644 packages/create-app/templates/default-app/packages/app/e2e-tests/app.test.ts create mode 100644 packages/create-app/templates/default-app/playwright.config.ts diff --git a/.changeset/twelve-clouds-design.md b/.changeset/twelve-clouds-design.md new file mode 100644 index 0000000000..d71d6caec0 --- /dev/null +++ b/.changeset/twelve-clouds-design.md @@ -0,0 +1,9 @@ +--- +'@backstage/create-app': patch +--- + +The E2E test setup based on Cypress has been replaced with one based on [Playwright](https://playwright.dev/). Migrating existing apps is not required as this is a standalone setup, only do so if you also want to switch from Cypress to Playwright. + +The scripts to run the E2E tests have been removed from `packages/app/package.json`, as they are now instead run from the root. Instead, a new script has been added to the root `package.json`, `yarn test:e2e`, which runs the E2E tests in development mode, unless `CI` is set in the environment. + +The Playwright setup uses utilities from the new `@backstage/e2e-test-utils` package to find and include all packages in the monorepo that have an `e2e-tests` folder. diff --git a/packages/create-app/src/lib/tasks.test.ts b/packages/create-app/src/lib/tasks.test.ts index c94bf43598..781e6a126c 100644 --- a/packages/create-app/src/lib/tasks.test.ts +++ b/packages/create-app/src/lib/tasks.test.ts @@ -66,6 +66,7 @@ jest.mock('./versions', () => ({ '@backstage/core-app-api': '1.0.0', '@backstage/core-components': '1.0.0', '@backstage/core-plugin-api': '1.0.0', + '@backstage/e2e-test-utils': '1.0.0', '@backstage/integration-react': '1.0.0', '@backstage/plugin-api-docs': '1.0.0', '@backstage/plugin-catalog': '1.0.0', diff --git a/packages/create-app/src/lib/versions.ts b/packages/create-app/src/lib/versions.ts index 72f5c2c9d5..67db8b4a78 100644 --- a/packages/create-app/src/lib/versions.ts +++ b/packages/create-app/src/lib/versions.ts @@ -41,6 +41,7 @@ import { version as config } from '../../../config/package.json'; import { version as coreAppApi } from '../../../core-app-api/package.json'; import { version as coreComponents } from '../../../core-components/package.json'; import { version as corePluginApi } from '../../../core-plugin-api/package.json'; +import { version as e2eTestUtils } from '../../../e2e-test-utils/package.json'; import { version as errors } from '../../../errors/package.json'; import { version as integrationReact } from '../../../integration-react/package.json'; import { version as testUtils } from '../../../test-utils/package.json'; @@ -92,6 +93,7 @@ export const packageVersions = { '@backstage/core-app-api': coreAppApi, '@backstage/core-components': coreComponents, '@backstage/core-plugin-api': corePluginApi, + '@backstage/e2e-test-utils': e2eTestUtils, '@backstage/errors': errors, '@backstage/integration-react': integrationReact, '@backstage/plugin-api-docs': pluginApiDocs, diff --git a/packages/create-app/templates/default-app/.gitignore.hbs b/packages/create-app/templates/default-app/.gitignore.hbs index d452ac2932..fbf813909c 100644 --- a/packages/create-app/templates/default-app/.gitignore.hbs +++ b/packages/create-app/templates/default-app/.gitignore.hbs @@ -49,3 +49,6 @@ site # vscode database functionality support files *.session.sql + +# E2E test reports +e2e-test-report/ diff --git a/packages/create-app/templates/default-app/package.json.hbs b/packages/create-app/templates/default-app/package.json.hbs index 9715331d8f..844a7bca9d 100644 --- a/packages/create-app/templates/default-app/package.json.hbs +++ b/packages/create-app/templates/default-app/package.json.hbs @@ -17,6 +17,7 @@ "clean": "backstage-cli repo clean", "test": "backstage-cli repo test", "test:all": "backstage-cli repo test --coverage", + "test:e2e": "playwright test", "fix": "backstage-cli repo fix", "lint": "backstage-cli repo lint --since origin/{{defaultBranch}}", "lint:all": "backstage-cli repo lint", @@ -31,6 +32,8 @@ }, "devDependencies": { "@backstage/cli": "^{{version '@backstage/cli'}}", + "@backstage/e2e-test-utils": "^{{version '@backstage/e2e-test-utils'}}", + "@playwright/test": "^1.32.3", "@spotify/prettier-config": "^12.0.0", "concurrently": "^8.0.0", "lerna": "^4.0.0", diff --git a/packages/create-app/templates/default-app/packages/app/cypress.config.js b/packages/create-app/templates/default-app/packages/app/cypress.config.js deleted file mode 100644 index 113d09ec84..0000000000 --- a/packages/create-app/templates/default-app/packages/app/cypress.config.js +++ /dev/null @@ -1,11 +0,0 @@ -const { defineConfig } = require('cypress'); - -module.exports = defineConfig({ - fixturesFolder: false, - retries: 3, - - e2e: { - supportFile: false, - baseUrl: 'http://localhost:3001', - }, -}); diff --git a/packages/create-app/templates/default-app/packages/app/cypress/.eslintrc.json b/packages/create-app/templates/default-app/packages/app/cypress/.eslintrc.json deleted file mode 100644 index b903ff250a..0000000000 --- a/packages/create-app/templates/default-app/packages/app/cypress/.eslintrc.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "plugins": ["cypress"], - "extends": ["plugin:cypress/recommended"], - "rules": { - "jest/expect-expect": [ - "error", - { - "assertFunctionNames": ["expect", "cy.contains", "cy.**.should"] - } - ] - } -} diff --git a/packages/create-app/templates/default-app/packages/app/cypress/e2e/app.cy.js b/packages/create-app/templates/default-app/packages/app/cypress/e2e/app.cy.js deleted file mode 100644 index 43fb2e32de..0000000000 --- a/packages/create-app/templates/default-app/packages/app/cypress/e2e/app.cy.js +++ /dev/null @@ -1,6 +0,0 @@ -describe('App', () => { - it('should render the catalog', () => { - cy.visit('/'); - cy.contains('My Company Catalog'); - }); -}); diff --git a/packages/create-app/templates/default-app/packages/app/e2e-tests/app.test.ts b/packages/create-app/templates/default-app/packages/app/e2e-tests/app.test.ts new file mode 100644 index 0000000000..d45bc0dbf0 --- /dev/null +++ b/packages/create-app/templates/default-app/packages/app/e2e-tests/app.test.ts @@ -0,0 +1,23 @@ +/* + * Copyright 2020 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 { test, expect } from '@playwright/test'; + +test('App should render the welcome page', async ({ page }) => { + await page.goto('/'); + + await expect(page.getByText('My Company Catalog')).toBeVisible(); +}); diff --git a/packages/create-app/templates/default-app/packages/app/package.json.hbs b/packages/create-app/templates/default-app/packages/app/package.json.hbs index b934b86945..598f049a4c 100644 --- a/packages/create-app/templates/default-app/packages/app/package.json.hbs +++ b/packages/create-app/templates/default-app/packages/app/package.json.hbs @@ -11,11 +11,7 @@ "build": "backstage-cli package build", "clean": "backstage-cli package clean", "test": "backstage-cli package test", - "lint": "backstage-cli package lint", - "test:e2e": "cross-env PORT=3001 start-server-and-test start http://localhost:3001 cy:dev", - "test:e2e:ci": "cross-env PORT=3001 start-server-and-test start http://localhost:3001 cy:run", - "cy:dev": "cypress open", - "cy:run": "cypress run --browser chrome" + "lint": "backstage-cli package lint" }, "dependencies": { "@backstage/app-defaults": "^{{version '@backstage/app-defaults'}}", @@ -54,15 +50,13 @@ }, "devDependencies": { "@backstage/test-utils": "^{{version '@backstage/test-utils'}}", + "@playwright/test": "^1.32.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@testing-library/dom": "^8.0.0", "@types/react-dom": "*", - "cross-env": "^7.0.0", - "cypress": "^12.0.0", - "eslint-plugin-cypress": "^2.10.3", - "start-server-and-test": "^1.10.11" + "cross-env": "^7.0.0" }, "browserslist": { "production": [ diff --git a/packages/create-app/templates/default-app/playwright.config.ts b/packages/create-app/templates/default-app/playwright.config.ts new file mode 100644 index 0000000000..37c7fb14c7 --- /dev/null +++ b/packages/create-app/templates/default-app/playwright.config.ts @@ -0,0 +1,60 @@ +/* + * 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 { defineConfig } from '@playwright/test'; +import { generateProjects } from '@backstage/e2e-test-utils/playwright'; + +/** + * See https://playwright.dev/docs/test-configuration. + */ +export default defineConfig({ + timeout: 60_000, + + expect: { + timeout: 5_000, + }, + + // Run your local dev server before starting the tests + webServer: process.env.CI + ? [] + : [ + { + command: 'yarn start', + port: 3000, + reuseExistingServer: true, + timeout: 60_000, + }, + ], + + forbidOnly: !!process.env.CI, + + retries: process.env.CI ? 2 : 0, + + reporter: [['html', { open: 'never', outputFolder: 'e2e-test-report' }]], + + use: { + actionTimeout: 0, + baseURL: + process.env.PLAYWRIGHT_URL ?? + (process.env.CI ? 'http://localhost:7007' : 'http://localhost:3000'), + screenshot: 'only-on-failure', + trace: 'on-first-retry', + }, + + outputDir: 'node_modules/.cache/e2e-test-results', + + projects: generateProjects(), // Find all packages with e2e-test folders +}); From 2e766f75e06e15e84188034ee16c7920e9badc0a Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 25 Sep 2023 16:56:25 +0200 Subject: [PATCH 062/110] e2e-tests: switch to running new e2e tests only for frontend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Johan Haals Signed-off-by: Patrik Oldsberg --- packages/e2e-test/package.json | 1 - packages/e2e-test/src/commands/run.ts | 76 ++------------ packages/e2e-test/src/lib/helpers.ts | 45 --------- yarn.lock | 136 ++++---------------------- 4 files changed, 26 insertions(+), 232 deletions(-) diff --git a/packages/e2e-test/package.json b/packages/e2e-test/package.json index 10e4cb3c47..74f9443d51 100644 --- a/packages/e2e-test/package.json +++ b/packages/e2e-test/package.json @@ -37,7 +37,6 @@ "handlebars": "^4.7.3", "mysql2": "^2.2.5", "pgtools": "^1.0.0", - "puppeteer": "^17.0.0", "tree-kill": "^1.2.2" }, "devDependencies": { diff --git a/packages/e2e-test/src/commands/run.ts b/packages/e2e-test/src/commands/run.ts index 6cca0fb987..ba2d81d568 100644 --- a/packages/e2e-test/src/commands/run.ts +++ b/packages/e2e-test/src/commands/run.ts @@ -20,13 +20,11 @@ import fetch from 'cross-fetch'; import handlebars from 'handlebars'; import killTree from 'tree-kill'; import { resolve as resolvePath, join as joinPath } from 'path'; -import puppeteer from 'puppeteer'; import path from 'path'; import { spawnPiped, runPlain, - waitForPageWithText, waitFor, waitForExit, print, @@ -42,6 +40,7 @@ const paths = findPaths(__dirname); const templatePackagePaths = [ 'packages/cli/templates/default-plugin/package.json.hbs', + 'packages/create-app/templates/default-app/package.json.hbs', 'packages/create-app/templates/default-app/packages/app/package.json.hbs', 'packages/create-app/templates/default-app/packages/backend/package.json.hbs', ]; @@ -66,8 +65,11 @@ export async function run() { print('Creating a Backstage Backend Plugin'); await createPlugin({ appDir, pluginId, select: 'backend-plugin' }); - print('Starting the app'); - await testAppServe(pluginId, appDir); + print(`Running 'yarn test:e2e' in newly created app with new plugin`); + await runPlain(['yarn', 'test:e2e'], { + cwd: appDir, + env: { ...process.env, CI: undefined }, + }); if ( Boolean(process.env.POSTGRES_USER) || @@ -297,15 +299,6 @@ async function createApp( await runPlain(['yarn', cmd], { cwd: appDir }); } - print(`Running 'yarn test:e2e:ci' in newly created app`); - await runPlain(['yarn', 'test:e2e:ci'], { - cwd: resolvePath(appDir, 'packages', 'app'), - env: { - ...process.env, - APP_CONFIG_app_baseUrl: '"http://localhost:3001"', - }, - }); - return appDir; } finally { child.kill(); @@ -381,63 +374,6 @@ async function createPlugin(options: { } } -/** - * Start serving the newly created app and make sure that the create plugin is rendering correctly - */ -async function testAppServe(pluginId: string, appDir: string) { - const startApp = spawnPiped(['yarn', 'start'], { - cwd: appDir, - env: { - ...process.env, - GITHUB_TOKEN: 'abc', - }, - }); - - let successful = false; - - let browser; - try { - for (let attempts = 1; ; attempts++) { - try { - browser = await puppeteer.launch(); - const page = await browser.newPage(); - - await page.goto('http://localhost:3000', { waitUntil: 'networkidle0' }); - - await waitForPageWithText(page, '/', 'My Company Catalog'); - await waitForPageWithText( - page, - `/${pluginId}`, - `Welcome to ${pluginId}!`, - ); - - print('Both App and Plugin loaded correctly'); - successful = true; - break; - } catch (error) { - if (attempts >= 20) { - throw new Error(`App serve test failed, ${error}`); - } - print(`App serve failed, trying again, ${error}`); - await new Promise(resolve => setTimeout(resolve, 1000)); - } - } - } finally { - // Kill entire process group, otherwise we'll end up with hanging serve processes - await new Promise((res, rej) => { - killTree(startApp.pid!, err => (err ? rej(err) : res())); - }); - } - - try { - await waitForExit(startApp); - } catch (error) { - if (!successful) { - throw error; - } - } -} - /** Drops PG databases */ async function dropDB(database: string, client: string) { try { diff --git a/packages/e2e-test/src/lib/helpers.ts b/packages/e2e-test/src/lib/helpers.ts index b3fd665fd2..fc5aefcff9 100644 --- a/packages/e2e-test/src/lib/helpers.ts +++ b/packages/e2e-test/src/lib/helpers.ts @@ -22,7 +22,6 @@ import { ChildProcess, } from 'child_process'; import { promisify } from 'util'; -import puppeteer from 'puppeteer'; const execFile = promisify(execFileCb); @@ -125,50 +124,6 @@ export async function waitForExit(child: ChildProcess) { ); } -export async function waitForPageWithText( - page: puppeteer.Page, - path: string, - text: string, - { intervalMs = 1000, maxFindAttempts = 50 } = {}, -) { - let findAttempts = 0; - for (;;) { - try { - const waitTimeMs = intervalMs * (findAttempts + 1); - console.log(`Attempting to load page at ${path}, waiting ${waitTimeMs}`); - await new Promise(resolve => setTimeout(resolve, waitTimeMs)); - - await page.goto(`http://localhost:3000${path}`, { - waitUntil: 'networkidle0', - }); - - const match = await page.evaluate( - textContent => - Array.from(document.querySelectorAll('*')).some( - el => el.textContent === textContent, - ), - text, - ); - - if (!match) { - throw new Error(`Expected to find text ${text}`); - } - - break; - } catch (error) { - console.log(error); - assertError(error); - - findAttempts++; - if (findAttempts >= maxFindAttempts) { - throw new Error( - `Failed to load page '${path}', max number of attempts reached`, - ); - } - } - } -} - export function print(msg: string) { return process.stdout.write(`${msg}\n`); } diff --git a/yarn.lock b/yarn.lock index 79a134018b..4de80ad8e4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4180,7 +4180,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/e2e-test-utils@workspace:packages/e2e-test-utils": +"@backstage/e2e-test-utils@workspace:*, @backstage/e2e-test-utils@workspace:packages/e2e-test-utils": version: 0.0.0-use.local resolution: "@backstage/e2e-test-utils@workspace:packages/e2e-test-utils" dependencies: @@ -18469,7 +18469,7 @@ __metadata: languageName: node linkType: hard -"@types/yauzl@npm:^2.10.0, @types/yauzl@npm:^2.9.1": +"@types/yauzl@npm:^2.10.0": version: 2.10.0 resolution: "@types/yauzl@npm:2.10.0" dependencies: @@ -20737,7 +20737,7 @@ __metadata: languageName: node linkType: hard -"buffer@npm:^5.2.1, buffer@npm:^5.5.0": +"buffer@npm:^5.5.0": version: 5.7.1 resolution: "buffer@npm:5.7.1" dependencies: @@ -22377,15 +22377,6 @@ __metadata: languageName: node linkType: hard -"cross-fetch@npm:3.1.5": - version: 3.1.5 - resolution: "cross-fetch@npm:3.1.5" - dependencies: - node-fetch: 2.6.7 - checksum: f6b8c6ee3ef993ace6277fd789c71b6acf1b504fd5f5c7128df4ef2f125a429e29cd62dc8c127523f04a5f2fa4771ed80e3f3d9695617f441425045f505cf3bb - languageName: node - linkType: hard - "cross-fetch@npm:^3.1.3, cross-fetch@npm:^3.1.5, cross-fetch@npm:^3.1.8 <4": version: 3.1.8 resolution: "cross-fetch@npm:3.1.8" @@ -23356,13 +23347,6 @@ __metadata: languageName: node linkType: hard -"devtools-protocol@npm:0.0.1036444": - version: 0.0.1036444 - resolution: "devtools-protocol@npm:0.0.1036444" - checksum: 6975c8def95a5e1a4207d6deb05322e335d6a37bdaa3e589cbd5bde40fbbe3ab0df2cfedb1b3ad2785401f208c150fd489a6a065a4624b56e4c0c4c1bfd89172 - languageName: node - linkType: hard - "dezalgo@npm:^1.0.0, dezalgo@npm:^1.0.4": version: 1.0.4 resolution: "dezalgo@npm:1.0.4" @@ -23722,7 +23706,6 @@ __metadata: mysql2: ^2.2.5 nodemon: ^3.0.1 pgtools: ^1.0.0 - puppeteer: ^17.0.0 tree-kill: ^1.2.2 ts-node: ^10.0.0 bin: @@ -25275,6 +25258,7 @@ __metadata: "@material-ui/lab": 4.0.0-alpha.61 "@octokit/rest": ^19.0.3 "@oriflame/backstage-plugin-score-card": ^0.7.0 + "@playwright/test": ^1.32.3 "@roadiehq/backstage-plugin-buildkite": ^2.0.8 "@roadiehq/backstage-plugin-github-insights": ^2.0.5 "@roadiehq/backstage-plugin-github-pull-requests": ^2.2.7 @@ -25652,23 +25636,6 @@ __metadata: languageName: node linkType: hard -"extract-zip@npm:2.0.1": - version: 2.0.1 - resolution: "extract-zip@npm:2.0.1" - dependencies: - "@types/yauzl": ^2.9.1 - debug: ^4.1.1 - get-stream: ^5.1.0 - yauzl: ^2.10.0 - dependenciesMeta: - "@types/yauzl": - optional: true - bin: - extract-zip: cli.js - checksum: 8cbda9debdd6d6980819cc69734d874ddd71051c9fe5bde1ef307ebcedfe949ba57b004894b585f758b7c9eeeea0e3d87f2dda89b7d25320459c2c9643ebb635 - languageName: node - linkType: hard - "extsprintf@npm:1.3.0": version: 1.3.0 resolution: "extsprintf@npm:1.3.0" @@ -27755,7 +27722,7 @@ __metadata: languageName: node linkType: hard -"https-proxy-agent@npm:5.0.1, https-proxy-agent@npm:^5.0.0, https-proxy-agent@npm:^5.0.1": +"https-proxy-agent@npm:^5.0.0, https-proxy-agent@npm:^5.0.1": version: 5.0.1 resolution: "https-proxy-agent@npm:5.0.1" dependencies: @@ -33190,20 +33157,6 @@ __metadata: languageName: node linkType: hard -"node-fetch@npm:2.6.7": - version: 2.6.7 - resolution: "node-fetch@npm:2.6.7" - dependencies: - whatwg-url: ^5.0.0 - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - checksum: 8d816ffd1ee22cab8301c7756ef04f3437f18dace86a1dae22cf81db8ef29c0bf6655f3215cb0cdb22b420b6fe141e64b26905e7f33f9377a7fa59135ea3e10b - languageName: node - linkType: hard - "node-fetch@npm:^1.0.1": version: 1.7.3 resolution: "node-fetch@npm:1.7.3" @@ -35712,13 +35665,6 @@ __metadata: languageName: node linkType: hard -"progress@npm:2.0.3": - version: 2.0.3 - resolution: "progress@npm:2.0.3" - checksum: f67403fe7b34912148d9252cb7481266a354bd99ce82c835f79070643bb3c6583d10dbcfda4d41e04bbc1d8437e9af0fb1e1f2135727878f5308682a579429b7 - languageName: node - linkType: hard - "prom-client@npm:^14.0.1": version: 14.2.0 resolution: "prom-client@npm:14.2.0" @@ -35904,7 +35850,7 @@ __metadata: languageName: node linkType: hard -"proxy-from-env@npm:1.1.0, proxy-from-env@npm:^1.1.0": +"proxy-from-env@npm:^1.1.0": version: 1.1.0 resolution: "proxy-from-env@npm:1.1.0" checksum: ed7fcc2ba0a33404958e34d95d18638249a68c430e30fcb6c478497d72739ba64ce9810a24f53a7d921d0c065e5b78e3822759800698167256b04659366ca4d4 @@ -35977,25 +35923,6 @@ __metadata: languageName: node linkType: hard -"puppeteer@npm:^17.0.0": - version: 17.1.3 - resolution: "puppeteer@npm:17.1.3" - dependencies: - cross-fetch: 3.1.5 - debug: 4.3.4 - devtools-protocol: 0.0.1036444 - extract-zip: 2.0.1 - https-proxy-agent: 5.0.1 - progress: 2.0.3 - proxy-from-env: 1.1.0 - rimraf: 3.0.2 - tar-fs: 2.1.1 - unbzip2-stream: 1.4.3 - ws: 8.8.1 - checksum: b4518956c661df4c37690d46b9c6744d42d59d01fe3764938b4b3af8de4c94ef11a9dfa6bc261798f5e5490c6dce4d4f555f05d42c735249683da3017faf4585 - languageName: node - linkType: hard - "pure-color@npm:^1.2.0": version: 1.3.0 resolution: "pure-color@npm:1.3.0" @@ -37789,17 +37716,6 @@ __metadata: languageName: node linkType: hard -"rimraf@npm:3.0.2, rimraf@npm:^3.0.0, rimraf@npm:^3.0.2": - version: 3.0.2 - resolution: "rimraf@npm:3.0.2" - dependencies: - glob: ^7.1.3 - bin: - rimraf: bin.js - checksum: 87f4164e396f0171b0a3386cc1877a817f572148ee13a7e113b238e48e8a9f2f31d009a92ec38a591ff1567d9662c6b67fd8818a2dbbaed74bc26a87a2a4a9a0 - languageName: node - linkType: hard - "rimraf@npm:^2.6.3": version: 2.7.1 resolution: "rimraf@npm:2.7.1" @@ -37811,6 +37727,17 @@ __metadata: languageName: node linkType: hard +"rimraf@npm:^3.0.0, rimraf@npm:^3.0.2": + version: 3.0.2 + resolution: "rimraf@npm:3.0.2" + dependencies: + glob: ^7.1.3 + bin: + rimraf: bin.js + checksum: 87f4164e396f0171b0a3386cc1877a817f572148ee13a7e113b238e48e8a9f2f31d009a92ec38a591ff1567d9662c6b67fd8818a2dbbaed74bc26a87a2a4a9a0 + languageName: node + linkType: hard + "rimraf@npm:~2.6.2": version: 2.6.3 resolution: "rimraf@npm:2.6.3" @@ -37970,11 +37897,13 @@ __metadata: "@backstage/cli": "workspace:*" "@backstage/codemods": "workspace:*" "@backstage/create-app": "workspace:*" + "@backstage/e2e-test-utils": "workspace:*" "@backstage/errors": "workspace:^" "@backstage/repo-tools": "workspace:*" "@changesets/cli": ^2.14.0 "@manypkg/get-packages": ^1.1.3 "@octokit/rest": ^19.0.3 + "@playwright/test": ^1.32.3 "@spotify/eslint-plugin": ^14.1.3 "@spotify/prettier-config": ^14.0.0 "@techdocs/cli": "workspace:*" @@ -39964,7 +39893,7 @@ __metadata: languageName: node linkType: hard -"tar-fs@npm:2.1.1, tar-fs@npm:^2.0.0, tar-fs@npm:^2.1.1": +"tar-fs@npm:^2.0.0, tar-fs@npm:^2.1.1": version: 2.1.1 resolution: "tar-fs@npm:2.1.1" dependencies: @@ -41011,16 +40940,6 @@ __metadata: languageName: node linkType: hard -"unbzip2-stream@npm:1.4.3": - version: 1.4.3 - resolution: "unbzip2-stream@npm:1.4.3" - dependencies: - buffer: ^5.2.1 - through: ^2.3.8 - checksum: 0e67c4a91f4fa0fc7b4045f8b914d3498c2fc2e8c39c359977708ec85ac6d6029840e97f508675fdbdf21fcb8d276ca502043406f3682b70f075e69aae626d1d - languageName: node - linkType: hard - "unc-path-regex@npm:^0.1.2": version: 0.1.2 resolution: "unc-path-regex@npm:0.1.2" @@ -42399,21 +42318,6 @@ __metadata: languageName: node linkType: hard -"ws@npm:8.8.1": - version: 8.8.1 - resolution: "ws@npm:8.8.1" - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - checksum: 2152cf862cae0693f3775bc688a6afb2e989d19d626d215e70f5fcd8eb55b1c3b0d3a6a4052905ec320e2d7734e20aeedbf9744496d62f15a26ad79cf4cf7dae - languageName: node - linkType: hard - "ws@npm:^5.2.0 || ^6.0.0 || ^7.0.0, ws@npm:^7.4.6": version: 7.5.9 resolution: "ws@npm:7.5.9" From 2a71c840963ae919c522926765f4f7ef15fc0cd6 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 25 Sep 2023 17:27:16 +0200 Subject: [PATCH 063/110] e2e-test-utils: entry point fix + API report Signed-off-by: Patrik Oldsberg --- .../e2e-test-utils/playwright-api-report.md | 15 +++++++++++++++ packages/e2e-test-utils/src/playwright.ts | 17 +++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 packages/e2e-test-utils/playwright-api-report.md create mode 100644 packages/e2e-test-utils/src/playwright.ts diff --git a/packages/e2e-test-utils/playwright-api-report.md b/packages/e2e-test-utils/playwright-api-report.md new file mode 100644 index 0000000000..7153f2e578 --- /dev/null +++ b/packages/e2e-test-utils/playwright-api-report.md @@ -0,0 +1,15 @@ +## API Report File for "@backstage/e2e-test-utils" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { PlaywrightTestConfig } from '@playwright/test'; + +// @public +export function failOnBrowserErrors(): void; + +// @public +export function generateProjects(): PlaywrightTestConfig['projects']; + +// (No @packageDocumentation comment for this package) +``` diff --git a/packages/e2e-test-utils/src/playwright.ts b/packages/e2e-test-utils/src/playwright.ts new file mode 100644 index 0000000000..63599d30db --- /dev/null +++ b/packages/e2e-test-utils/src/playwright.ts @@ -0,0 +1,17 @@ +/* + * 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. + */ + +export * from './playwright/index'; From a82a4857cd810b20bea44f970263c5224a8f51a7 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 26 Sep 2023 10:14:24 +0200 Subject: [PATCH 064/110] e2e-test-utils: move playwright to peer dep Signed-off-by: Patrik Oldsberg --- packages/e2e-test-utils/package.json | 9 ++++++++- yarn.lock | 6 +++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/packages/e2e-test-utils/package.json b/packages/e2e-test-utils/package.json index ee18258768..33e03edb3e 100644 --- a/packages/e2e-test-utils/package.json +++ b/packages/e2e-test-utils/package.json @@ -36,7 +36,6 @@ }, "dependencies": { "@manypkg/get-packages": "^1.1.3", - "@playwright/test": "^1.32.3", "fs-extra": "^10.1.0" }, "devDependencies": { @@ -44,6 +43,14 @@ "@backstage/cli-node": "workspace:^", "@types/fs-extra": "^9.0.1" }, + "peerDependencies": { + "@playwright/test": "^1.32.3" + }, + "peerDependenciesMeta": { + "@playwright/test": { + "optional": true + } + }, "files": [ "dist" ] diff --git a/yarn.lock b/yarn.lock index 4de80ad8e4..00e23676da 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4187,9 +4187,13 @@ __metadata: "@backstage/cli": "workspace:^" "@backstage/cli-node": "workspace:^" "@manypkg/get-packages": ^1.1.3 - "@playwright/test": ^1.32.3 "@types/fs-extra": ^9.0.1 fs-extra: ^10.1.0 + peerDependencies: + "@playwright/test": ^1.32.3 + peerDependenciesMeta: + "@playwright/test": + optional: true languageName: unknown linkType: soft From 1268c09a15010aabd80cd2bd05b4961dde851d33 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 26 Sep 2023 10:14:58 +0200 Subject: [PATCH 065/110] e2e-test-utils: update install instructions in README Signed-off-by: Patrik Oldsberg --- packages/e2e-test-utils/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/e2e-test-utils/README.md b/packages/e2e-test-utils/README.md index e3e0334020..d9459dc64a 100644 --- a/packages/e2e-test-utils/README.md +++ b/packages/e2e-test-utils/README.md @@ -8,5 +8,5 @@ Install the package via Yarn: ```sh cd # if within a monorepo -yarn add @backstage/e2e-test-utils +yarn add --dev @backstage/e2e-test-utils ``` From e34919037404548f994dbe113acb908f6f0975aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Tue, 26 Sep 2023 10:41:14 +0200 Subject: [PATCH 066/110] update changeset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/polite-donuts-fail.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/polite-donuts-fail.md b/.changeset/polite-donuts-fail.md index 4b71dfddc3..9c03faaf44 100644 --- a/.changeset/polite-donuts-fail.md +++ b/.changeset/polite-donuts-fail.md @@ -2,4 +2,4 @@ '@backstage/plugin-catalog-backend': patch --- -Internal refactors as a path toward #18062 +Internal refactors, laying the foundation for later introducing deferred stitching (see #18062). From 773ea341d28cc87176b74979798718cb06012f55 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 26 Sep 2023 11:05:37 +0200 Subject: [PATCH 067/110] config-loader: retry empty files Signed-off-by: Patrik Oldsberg --- .changeset/shy-clouds-reflect.md | 5 +++++ packages/config-loader/src/sources/FileConfigSource.ts | 10 +++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 .changeset/shy-clouds-reflect.md diff --git a/.changeset/shy-clouds-reflect.md b/.changeset/shy-clouds-reflect.md new file mode 100644 index 0000000000..2861bad9f3 --- /dev/null +++ b/.changeset/shy-clouds-reflect.md @@ -0,0 +1,5 @@ +--- +'@backstage/config-loader': patch +--- + +The `FileConfigSource` will now retry file reading after a short delay if it reads an empty file. This is to avoid flakiness during watch mode where change events can trigger before the file content has been written. diff --git a/packages/config-loader/src/sources/FileConfigSource.ts b/packages/config-loader/src/sources/FileConfigSource.ts index da31c128a0..1de0fbf2d8 100644 --- a/packages/config-loader/src/sources/FileConfigSource.ts +++ b/packages/config-loader/src/sources/FileConfigSource.ts @@ -47,7 +47,15 @@ export interface FileConfigSourceOptions { async function readFile(path: string): Promise { try { - return await fs.readFile(path, 'utf8'); + const content = await fs.readFile(path, 'utf8'); + // During watching we may sometimes read files too early before the file content has been written. + // We never expect the writing to take a long time, but if we encounter an empty file then check + // again after a short delay for safety. + if (content === '') { + await new Promise(resolve => setTimeout(resolve, 10)); + return await fs.readFile(path, 'utf8'); + } + return content; } catch (error) { if (error.code === 'ENOENT') { return undefined; From 7077dbf1317bdf2c7e385f00bf7ae954ae6c41cb Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 23 Sep 2023 17:00:31 +0200 Subject: [PATCH 068/110] cli: make next backend start the default Signed-off-by: Patrik Oldsberg --- .changeset/itchy-rabbits-exist.md | 7 +++++++ .github/vale/Vocab/Backstage/accept.txt | 1 + packages/backend-next/package.json | 2 +- packages/cli/src/commands/start/startBackend.ts | 2 +- 4 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 .changeset/itchy-rabbits-exist.md diff --git a/.changeset/itchy-rabbits-exist.md b/.changeset/itchy-rabbits-exist.md new file mode 100644 index 0000000000..acac771a97 --- /dev/null +++ b/.changeset/itchy-rabbits-exist.md @@ -0,0 +1,7 @@ +--- +'@backstage/cli': minor +--- + +The new backend start command that used to be enabled by setting `EXPERIMENTAL_BACKEND_START` is now the default. To revert to the old behavior, set `LEGACY_BACKEND_START` instead. + +This new command is no longer based on Webpack, but instead uses Node.js loaders to transpile on the fly. Rather than hot reloading modules the entire backend is now restarted on change, but the SQLite database state is still maintained across restarts via a parent process. diff --git a/.github/vale/Vocab/Backstage/accept.txt b/.github/vale/Vocab/Backstage/accept.txt index 4e3ef18a65..aadbaa3985 100644 --- a/.github/vale/Vocab/Backstage/accept.txt +++ b/.github/vale/Vocab/Backstage/accept.txt @@ -401,6 +401,7 @@ tooltip tooltips touchpoint transpilation +transpile transpiled transpiler transpilers diff --git a/packages/backend-next/package.json b/packages/backend-next/package.json index 1ac1be2681..3a2c337013 100644 --- a/packages/backend-next/package.json +++ b/packages/backend-next/package.json @@ -18,7 +18,7 @@ "backstage" ], "scripts": { - "start": "EXPERIMENTAL_BACKEND_START=1 backstage-cli package start", + "start": "backstage-cli package start", "build": "backstage-cli package build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", diff --git a/packages/cli/src/commands/start/startBackend.ts b/packages/cli/src/commands/start/startBackend.ts index 622eeb9d1b..967a1108a0 100644 --- a/packages/cli/src/commands/start/startBackend.ts +++ b/packages/cli/src/commands/start/startBackend.ts @@ -36,7 +36,7 @@ export async function startBackend(options: StartBackendOptions) { }); await waitForExit(); - } else if (process.env.EXPERIMENTAL_BACKEND_START) { + } else if (!process.env.LEGACY_BACKEND_START) { const waitForExit = await startBackendExperimental({ entry: 'src/index', checksEnabled: false, // not supported From 1c3d6fa2b24b6acab574be8a39a7270db41ea6d5 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 23 Sep 2023 17:04:27 +0200 Subject: [PATCH 069/110] backend-common: deprecate hot reload helpers Signed-off-by: Patrik Oldsberg --- .changeset/wet-timers-chew.md | 5 +++++ packages/backend-common/api-report.md | 4 ++-- packages/backend-common/src/hot.ts | 2 ++ 3 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 .changeset/wet-timers-chew.md diff --git a/.changeset/wet-timers-chew.md b/.changeset/wet-timers-chew.md new file mode 100644 index 0000000000..3be6368331 --- /dev/null +++ b/.changeset/wet-timers-chew.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-common': patch +--- + +The `useHotCleanup` and `useHotMemoize` helpers are now deprecated, since hot module reloads for backend are being phased out. diff --git a/packages/backend-common/api-report.md b/packages/backend-common/api-report.md index f0fa15efb0..ab640ccd9b 100644 --- a/packages/backend-common/api-report.md +++ b/packages/backend-common/api-report.md @@ -785,12 +785,12 @@ export type UrlReadersOptions = { factories?: ReaderFactory[]; }; -// @public +// @public @deprecated export function useHotCleanup( _module: NodeModule, cancelEffect: () => void, ): void; -// @public +// @public @deprecated export function useHotMemoize(_module: NodeModule, valueFactory: () => T): T; ``` diff --git a/packages/backend-common/src/hot.ts b/packages/backend-common/src/hot.ts index 7148778b8c..94ebf52307 100644 --- a/packages/backend-common/src/hot.ts +++ b/packages/backend-common/src/hot.ts @@ -47,6 +47,7 @@ function findAllAncestors(_module: NodeModule): NodeModule[] { * Useful for cleaning intervals, timers, requests etc * * @public + * @deprecated Hot module reloading is no longer supported for backends. * @example * ```ts * const intervalId = setInterval(doStuff, 1000); @@ -80,6 +81,7 @@ const CURRENT_HOT_MEMOIZE_INDEX_KEY = 'backstage.io/hmr-memoize-key'; * stateful parts of the backend, e.g. to retain a database. * * @public + * @deprecated Hot module reloading is no longer supported for backends. * @example * ```ts * const db = useHotMemoize(module, () => createDB(dbParams)); From a5d592d0ad037eb9d764d6329e423198950a95e8 Mon Sep 17 00:00:00 2001 From: Andy Muldoon Date: Thu, 14 Sep 2023 12:34:47 +0100 Subject: [PATCH 070/110] Migrate sonarqube-backend plugin to the new backend system #18320 Signed-off-by: Andy Muldoon --- .changeset/clean-forks-love.md | 5 ++ packages/backend-next/package.json | 1 + packages/backend-next/src/index.ts | 1 + plugins/sonarqube-backend/README.md | 14 +++++ plugins/sonarqube-backend/api-report.md | 5 ++ plugins/sonarqube-backend/package.json | 1 + plugins/sonarqube-backend/src/index.ts | 1 + plugins/sonarqube-backend/src/plugin.test.tsx | 22 +++++++ plugins/sonarqube-backend/src/plugin.ts | 57 +++++++++++++++++++ yarn.lock | 4 +- 10 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 .changeset/clean-forks-love.md create mode 100644 plugins/sonarqube-backend/src/plugin.test.tsx create mode 100644 plugins/sonarqube-backend/src/plugin.ts diff --git a/.changeset/clean-forks-love.md b/.changeset/clean-forks-love.md new file mode 100644 index 0000000000..f81fe3066b --- /dev/null +++ b/.changeset/clean-forks-love.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-sonarqube-backend': patch +--- + +Added support for the [new backend system](https://backstage.io/docs/backend-system/) diff --git a/packages/backend-next/package.json b/packages/backend-next/package.json index edda247a5a..0e8ed62fbb 100644 --- a/packages/backend-next/package.json +++ b/packages/backend-next/package.json @@ -52,6 +52,7 @@ "@backstage/plugin-search-backend-module-explore": "workspace:^", "@backstage/plugin-search-backend-module-techdocs": "workspace:^", "@backstage/plugin-search-backend-node": "workspace:^", + "@backstage/plugin-sonarqube-backend": "workspace:^", "@backstage/plugin-techdocs-backend": "workspace:^", "@backstage/plugin-todo-backend": "workspace:^" }, diff --git a/packages/backend-next/src/index.ts b/packages/backend-next/src/index.ts index 4e99732a11..e61e303e9c 100644 --- a/packages/backend-next/src/index.ts +++ b/packages/backend-next/src/index.ts @@ -44,5 +44,6 @@ backend.add(import('@backstage/plugin-search-backend-module-techdocs/alpha')); backend.add(import('@backstage/plugin-search-backend/alpha')); backend.add(import('@backstage/plugin-techdocs-backend/alpha')); backend.add(import('@backstage/plugin-todo-backend')); +backend.add(import('@backstage/plugin-sonarqube-backend')); backend.start(); diff --git a/plugins/sonarqube-backend/README.md b/plugins/sonarqube-backend/README.md index b417fea7c4..1a1e2ae2dd 100644 --- a/plugins/sonarqube-backend/README.md +++ b/plugins/sonarqube-backend/README.md @@ -2,6 +2,20 @@ Welcome to the sonarqube-backend backend plugin! +## New Backend System + +The Sonarqube backend plugin has support for the [new backend system](https://backstage.io/docs/backend-system/), here's how you can set that up: + +In your `packages/backend/src/index.ts` make the following changes: + +```diff + import { createBackend } from '@backstage/backend-defaults'; + const backend = createBackend(); + // ... other feature additions ++ backend.add(import('@backstage/plugin-sonarqube-backend'); + backend.start(); +``` + ## Integrating into a backstage instance This plugin needs to be added to an existing backstage instance. diff --git a/plugins/sonarqube-backend/api-report.md b/plugins/sonarqube-backend/api-report.md index 535db37185..c3c684f9d4 100644 --- a/plugins/sonarqube-backend/api-report.md +++ b/plugins/sonarqube-backend/api-report.md @@ -3,6 +3,7 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; import { Config } from '@backstage/config'; import express from 'express'; import { Logger } from 'winston'; @@ -72,5 +73,9 @@ export interface SonarqubeMeasure { value: string; } +// @public +const sonarqubePlugin: () => BackendFeature; +export default sonarqubePlugin; + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/sonarqube-backend/package.json b/plugins/sonarqube-backend/package.json index ec5a2ed887..2cb0fd9636 100644 --- a/plugins/sonarqube-backend/package.json +++ b/plugins/sonarqube-backend/package.json @@ -29,6 +29,7 @@ }, "dependencies": { "@backstage/backend-common": "workspace:^", + "@backstage/backend-plugin-api": "workspace:^", "@backstage/config": "workspace:^", "@backstage/errors": "workspace:^", "@types/express": "*", diff --git a/plugins/sonarqube-backend/src/index.ts b/plugins/sonarqube-backend/src/index.ts index c91aef09f8..4bb82df34e 100644 --- a/plugins/sonarqube-backend/src/index.ts +++ b/plugins/sonarqube-backend/src/index.ts @@ -16,3 +16,4 @@ export * from './service/router'; export * from './service/sonarqubeInfoProvider'; +export { sonarqubePlugin as default } from './plugin'; diff --git a/plugins/sonarqube-backend/src/plugin.test.tsx b/plugins/sonarqube-backend/src/plugin.test.tsx new file mode 100644 index 0000000000..9b26a88862 --- /dev/null +++ b/plugins/sonarqube-backend/src/plugin.test.tsx @@ -0,0 +1,22 @@ +/* + * 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 { sonarqubePlugin } from './plugin'; + +describe('sonarqube', () => { + it('should export the sonarqube plugin', () => { + expect(sonarqubePlugin).toBeDefined(); + }); +}); diff --git a/plugins/sonarqube-backend/src/plugin.ts b/plugins/sonarqube-backend/src/plugin.ts new file mode 100644 index 0000000000..fd4fb77fb4 --- /dev/null +++ b/plugins/sonarqube-backend/src/plugin.ts @@ -0,0 +1,57 @@ +/* + * 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 { loggerToWinstonLogger } from '@backstage/backend-common'; +import { + createBackendPlugin, + coreServices, +} from '@backstage/backend-plugin-api'; +import { DefaultSonarqubeInfoProvider } from './service/sonarqubeInfoProvider'; +import { createRouter } from './service/router'; + +/** + * Sonarqube backend plugin + * + * @public + */ +export const sonarqubePlugin = createBackendPlugin({ + pluginId: 'sonarqube', + register(env) { + env.registerInit({ + deps: { + logger: coreServices.logger, + config: coreServices.rootConfig, + httpRouter: coreServices.httpRouter, + }, + async init({ logger, config, httpRouter }) { + const winstonLogger = loggerToWinstonLogger(logger); + httpRouter.use( + await createRouter({ + /** + * Logger for logging purposes + */ + logger: winstonLogger, + /** + * Info provider to be able to get all necessary information for the APIs + */ + sonarqubeInfoProvider: + DefaultSonarqubeInfoProvider.fromConfig(config), + }), + ); + }, + }); + }, +}); diff --git a/yarn.lock b/yarn.lock index c0a75005bf..cf41441920 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9219,11 +9219,12 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-sonarqube-backend@workspace:plugins/sonarqube-backend": +"@backstage/plugin-sonarqube-backend@workspace:^, @backstage/plugin-sonarqube-backend@workspace:plugins/sonarqube-backend": version: 0.0.0-use.local resolution: "@backstage/plugin-sonarqube-backend@workspace:plugins/sonarqube-backend" dependencies: "@backstage/backend-common": "workspace:^" + "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" @@ -25973,6 +25974,7 @@ __metadata: "@backstage/plugin-search-backend-module-explore": "workspace:^" "@backstage/plugin-search-backend-module-techdocs": "workspace:^" "@backstage/plugin-search-backend-node": "workspace:^" + "@backstage/plugin-sonarqube-backend": "workspace:^" "@backstage/plugin-techdocs-backend": "workspace:^" "@backstage/plugin-todo-backend": "workspace:^" languageName: unknown From cbab1d1da8a7bf7b13c3015a2e7668f611a9742b Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 26 Sep 2023 11:59:17 +0200 Subject: [PATCH 071/110] e2e-test: ignore ESM Loader warning Signed-off-by: Patrik Oldsberg --- packages/e2e-test/src/commands/run.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/e2e-test/src/commands/run.ts b/packages/e2e-test/src/commands/run.ts index ba2d81d568..cf95f6856d 100644 --- a/packages/e2e-test/src/commands/run.ts +++ b/packages/e2e-test/src/commands/run.ts @@ -463,6 +463,10 @@ async function testBackendStart(appDir: string, ...args: string[]) { !l.includes('check the migration guide at https://a.co/7PzMCcy') && !l.includes( '(Use `node --trace-warnings ...` to show where the warning was created)', + ) && + !l.includes('Custom ESM Loaders is an experimental feature') && + !l.includes( + 'ExperimentalWarning: `globalPreload` is planned for removal', ), ).length !== 0 ); From 3bbb80be45c9f1e58de16942ea3b212be3648d94 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 26 Sep 2023 13:26:44 +0200 Subject: [PATCH 072/110] Apply suggestions from code review Signed-off-by: Patrik Oldsberg --- .changeset/purple-chefs-wait.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/purple-chefs-wait.md b/.changeset/purple-chefs-wait.md index 36cbe99095..9a8b1f9799 100644 --- a/.changeset/purple-chefs-wait.md +++ b/.changeset/purple-chefs-wait.md @@ -1,5 +1,5 @@ --- -'@backstage/plugin-api-docs': minor +'@backstage/plugin-api-docs': patch --- Adding `requestInterceptor` option to `api-docs` and pass it to SwaggerUI. This will enable to configure a proxy or headers to be sent to all the request made through the `Try it out` button on SwaggerUI. From d19a827ef1c74510d84c307c0028274f041145ef Mon Sep 17 00:00:00 2001 From: Brian Forbis Date: Fri, 16 Jun 2023 16:58:28 -0400 Subject: [PATCH 073/110] Add dynamic yaml example to MissingAnnotation component Signed-off-by: Brian Forbis --- .changeset/yellow-rings-invent.md | 5 ++ packages/core-components/package.json | 2 + .../MissingAnnotationEmptyState.tsx | 75 ++++++++++--------- yarn.lock | 2 + 4 files changed, 50 insertions(+), 34 deletions(-) create mode 100644 .changeset/yellow-rings-invent.md diff --git a/.changeset/yellow-rings-invent.md b/.changeset/yellow-rings-invent.md new file mode 100644 index 0000000000..f0335ff492 --- /dev/null +++ b/.changeset/yellow-rings-invent.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': patch +--- + +MissingAnnotationEmptyState component can now dynamically generate a YAML example based off the current entity being used. diff --git a/packages/core-components/package.json b/packages/core-components/package.json index d8cc5057ff..e68320ad0c 100644 --- a/packages/core-components/package.json +++ b/packages/core-components/package.json @@ -33,9 +33,11 @@ "start": "backstage-cli package start" }, "dependencies": { + "@backstage/catalog-model": "workspace:^", "@backstage/config": "workspace:^", "@backstage/core-plugin-api": "workspace:^", "@backstage/errors": "workspace:^", + "@backstage/plugin-catalog-react": "workspace:^", "@backstage/theme": "workspace:^", "@backstage/version-bridge": "workspace:^", "@date-io/core": "^1.3.13", diff --git a/packages/core-components/src/components/EmptyState/MissingAnnotationEmptyState.tsx b/packages/core-components/src/components/EmptyState/MissingAnnotationEmptyState.tsx index 9fc9eee959..d7c8558614 100644 --- a/packages/core-components/src/components/EmptyState/MissingAnnotationEmptyState.tsx +++ b/packages/core-components/src/components/EmptyState/MissingAnnotationEmptyState.tsx @@ -25,23 +25,8 @@ import { CodeSnippet } from '../CodeSnippet'; import { Link } from '../Link'; import { EmptyState } from './EmptyState'; -const COMPONENT_YAML_TEMPLATE = `apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: example - description: example.com - annotations: - ANNOTATION: value -spec: - type: website - lifecycle: production - owner: user:guest`; - -const ANNOTATION_REGEXP = /^.*ANNOTATION.*$/m; -const ANNOTATION_YAML = COMPONENT_YAML_TEMPLATE.match(ANNOTATION_REGEXP)![0]; -const ANNOTATION_LINE = COMPONENT_YAML_TEMPLATE.split('\n').findIndex(line => - ANNOTATION_REGEXP.test(line), -); +import { useEntity } from '@backstage/plugin-catalog-react'; +import { Entity } from '@backstage/catalog-model'; type Props = { annotation: string | string[]; @@ -62,19 +47,38 @@ const useStyles = makeStyles( { name: 'BackstageMissingAnnotationEmptyState' }, ); -function generateLineNumbers(lineCount: number) { - return Array.from(Array(lineCount + 1).keys(), i => i + ANNOTATION_LINE); +function generateYamlExample( + entity: Entity, + annotations: string[], +): { yamlText: string; lineNumbers: number[] } { + const kind = entity.kind || 'Component'; + const name = entity.metadata.name || 'example'; + const type = entity.spec?.type || 'website'; + const owner = entity.spec?.owner || 'user:default/guest'; + + const yamlText = `apiVersion: backstage.io/v1alpha1 +kind: ${kind} +metadata: + name: ${name} + annotations:${annotations.map(ann => `\n ${ann}: value`).join('')} +spec: + type: ${type} + owner: ${owner}`; + + let line = 6; // Line 6 is the line number that annotations are added to. + const lineNumbers: number[] = []; + annotations.forEach(() => { + lineNumbers.push(line); + line++; + }); + + return { + yamlText, + lineNumbers, + }; } -function generateComponentYaml(annotations: string[]) { - const annotationYaml = annotations - .map(ann => ANNOTATION_YAML.replace('ANNOTATION', ann)) - .join('\n'); - - return COMPONENT_YAML_TEMPLATE.replace(ANNOTATION_YAML, annotationYaml); -} - -function generateDescription(annotations: string[]) { +function generateDescription(annotations: string[], entityKind = 'Component') { const isSingular = annotations.length <= 1; return ( <> @@ -87,13 +91,14 @@ function generateDescription(annotations: string[]) { ))}{' '} {isSingular ? 'is' : 'are'} missing. You need to add the{' '} - {isSingular ? 'annotation' : 'annotations'} to your component if you want - to enable this tool. + {isSingular ? 'annotation' : 'annotations'} to your {entityKind} if you + want to enable this tool. ); } export function MissingAnnotationEmptyState(props: Props) { + const { entity } = useEntity(); const { annotation, readMoreUrl } = props; const annotations = Array.isArray(annotation) ? annotation : [annotation]; const url = @@ -101,23 +106,25 @@ export function MissingAnnotationEmptyState(props: Props) { 'https://backstage.io/docs/features/software-catalog/well-known-annotations'; const classes = useStyles(); + const entityKind = entity.kind || 'Component'; + const { yamlText, lineNumbers } = generateYamlExample(entity, annotations); return ( - Add the annotation to your component YAML as shown in the + Add the annotation to your {entityKind} YAML as shown in the highlighted example below: diff --git a/yarn.lock b/yarn.lock index b22617f10b..3272752df8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3973,11 +3973,13 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/core-components@workspace:packages/core-components" dependencies: + "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" "@backstage/core-app-api": "workspace:^" "@backstage/core-plugin-api": "workspace:^" "@backstage/errors": "workspace:^" + "@backstage/plugin-catalog-react": "workspace:^" "@backstage/test-utils": "workspace:^" "@backstage/theme": "workspace:^" "@backstage/version-bridge": "workspace:^" From dc2473018031b607aee1627ed8d29ad889d4cbd2 Mon Sep 17 00:00:00 2001 From: Brian Forbis Date: Fri, 16 Jun 2023 19:01:14 -0400 Subject: [PATCH 074/110] Catch when entity context doesnt exist Signed-off-by: Brian Forbis --- .../MissingAnnotationEmptyState.tsx | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/packages/core-components/src/components/EmptyState/MissingAnnotationEmptyState.tsx b/packages/core-components/src/components/EmptyState/MissingAnnotationEmptyState.tsx index d7c8558614..c89129670a 100644 --- a/packages/core-components/src/components/EmptyState/MissingAnnotationEmptyState.tsx +++ b/packages/core-components/src/components/EmptyState/MissingAnnotationEmptyState.tsx @@ -48,13 +48,13 @@ const useStyles = makeStyles( ); function generateYamlExample( - entity: Entity, annotations: string[], + entity?: Entity, ): { yamlText: string; lineNumbers: number[] } { - const kind = entity.kind || 'Component'; - const name = entity.metadata.name || 'example'; - const type = entity.spec?.type || 'website'; - const owner = entity.spec?.owner || 'user:default/guest'; + const kind = entity?.kind || 'Component'; + const name = entity?.metadata.name || 'example'; + const type = entity?.spec?.type || 'website'; + const owner = entity?.spec?.owner || 'user:default/guest'; const yamlText = `apiVersion: backstage.io/v1alpha1 kind: ${kind} @@ -98,7 +98,14 @@ function generateDescription(annotations: string[], entityKind = 'Component') { } export function MissingAnnotationEmptyState(props: Props) { - const { entity } = useEntity(); + let entity: Entity | undefined; + try { + const entityContext = useEntity(); + entity = entityContext.entity; + } catch (err) { + // ignore when entity context doesnt exist + } + const { annotation, readMoreUrl } = props; const annotations = Array.isArray(annotation) ? annotation : [annotation]; const url = @@ -106,8 +113,8 @@ export function MissingAnnotationEmptyState(props: Props) { 'https://backstage.io/docs/features/software-catalog/well-known-annotations'; const classes = useStyles(); - const entityKind = entity.kind || 'Component'; - const { yamlText, lineNumbers } = generateYamlExample(entity, annotations); + const entityKind = entity?.kind || 'Component'; + const { yamlText, lineNumbers } = generateYamlExample(annotations, entity); return ( Date: Sat, 17 Jun 2023 00:31:32 -0400 Subject: [PATCH 075/110] Fix test Signed-off-by: Brian Forbis --- .../src/components/EntityVaultCard/EntityVaultCard.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/vault/src/components/EntityVaultCard/EntityVaultCard.test.tsx b/plugins/vault/src/components/EntityVaultCard/EntityVaultCard.test.tsx index f46aa1e4c2..9450ddc41d 100644 --- a/plugins/vault/src/components/EntityVaultCard/EntityVaultCard.test.tsx +++ b/plugins/vault/src/components/EntityVaultCard/EntityVaultCard.test.tsx @@ -46,7 +46,7 @@ describe('EntityVaultCard', () => { , ); expect( - rendered.getByText(/Add the annotation to your component YAML/), + rendered.getByText(/Add the annotation to your Component YAML/), ).toBeInTheDocument(); }); }); From c8ec0dea4afc2b076bb1fe7ef5acc91c75072792 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Tue, 26 Sep 2023 14:00:41 +0200 Subject: [PATCH 076/110] create-app: create unique temp directory for each execution Signed-off-by: Johan Haals --- .changeset/calm-scissors-rescue.md | 5 +++++ packages/create-app/src/createApp.test.ts | 7 +------ packages/create-app/src/createApp.ts | 8 ++++---- packages/create-app/src/lib/tasks.test.ts | 25 ----------------------- packages/create-app/src/lib/tasks.ts | 16 --------------- 5 files changed, 10 insertions(+), 51 deletions(-) create mode 100644 .changeset/calm-scissors-rescue.md diff --git a/.changeset/calm-scissors-rescue.md b/.changeset/calm-scissors-rescue.md new file mode 100644 index 0000000000..4a5318d240 --- /dev/null +++ b/.changeset/calm-scissors-rescue.md @@ -0,0 +1,5 @@ +--- +'@backstage/create-app': patch +--- + +Create unique temp directory for each `create-app` execution. diff --git a/packages/create-app/src/createApp.test.ts b/packages/create-app/src/createApp.test.ts index 47c62520e0..7cb9733567 100644 --- a/packages/create-app/src/createApp.test.ts +++ b/packages/create-app/src/createApp.test.ts @@ -36,10 +36,6 @@ const templatingMock = jest.spyOn(tasks, 'templatingTask'); const checkAppExistsMock = jest.spyOn(tasks, 'checkAppExistsTask'); const tryInitGitRepositoryMock = jest.spyOn(tasks, 'tryInitGitRepository'); const readGitConfig = jest.spyOn(tasks, 'readGitConfig'); -const createTemporaryAppFolderMock = jest.spyOn( - tasks, - 'createTemporaryAppFolderTask', -); const moveAppMock = jest.spyOn(tasks, 'moveAppTask'); const buildAppMock = jest.spyOn(tasks, 'buildAppTask'); @@ -73,7 +69,6 @@ describe('command entrypoint', () => { const cmd = {} as unknown as Command; await createApp(cmd); expect(checkAppExistsMock).toHaveBeenCalled(); - expect(createTemporaryAppFolderMock).toHaveBeenCalled(); expect(tryInitGitRepositoryMock).toHaveBeenCalled(); expect(templatingMock).toHaveBeenCalled(); expect(templatingMock.mock.lastCall?.[0]).toEqual( @@ -85,7 +80,7 @@ describe('command entrypoint', () => { 'default-app', ), ); - expect(templatingMock.mock.lastCall?.[1]).toEqual( + expect(templatingMock.mock.lastCall?.[1]).toContain( path.join(tmpdir(), 'MyApp'), ); expect(moveAppMock).toHaveBeenCalled(); diff --git a/packages/create-app/src/createApp.ts b/packages/create-app/src/createApp.ts index efa299a3c9..bfa53f03c0 100644 --- a/packages/create-app/src/createApp.ts +++ b/packages/create-app/src/createApp.ts @@ -20,12 +20,12 @@ import inquirer, { Answers } from 'inquirer'; import { resolve as resolvePath } from 'path'; import { findPaths } from '@backstage/cli-common'; import os from 'os'; +import fs from 'fs-extra'; import { Task, buildAppTask, checkAppExistsTask, checkPathExistsTask, - createTemporaryAppFolderTask, moveAppTask, templatingTask, tryInitGitRepository, @@ -37,7 +37,6 @@ const DEFAULT_BRANCH = 'master'; export default async (opts: OptionValues): Promise => { /* eslint-disable-next-line no-restricted-syntax */ const paths = findPaths(__dirname); - const answers: Answers = await inquirer.prompt([ { type: 'input', @@ -68,7 +67,6 @@ export default async (opts: OptionValues): Promise => { const templateDir = opts.templatePath ? paths.resolveTarget(opts.templatePath) : paths.resolveOwn('templates/default-app'); - const tempDir = resolvePath(os.tmpdir(), answers.name); // Use `--path` argument as application directory when specified, otherwise // create a directory using `answers.name` @@ -100,7 +98,9 @@ export default async (opts: OptionValues): Promise => { await checkAppExistsTask(paths.targetDir, answers.name); Task.section('Creating a temporary app directory'); - await createTemporaryAppFolderTask(tempDir); + const tempDir = await fs.mkdtemp( + resolvePath(resolvePath(os.tmpdir(), answers.name)), + ); Task.section('Preparing files'); await templatingTask(templateDir, tempDir, { diff --git a/packages/create-app/src/lib/tasks.test.ts b/packages/create-app/src/lib/tasks.test.ts index 781e6a126c..68afdc9222 100644 --- a/packages/create-app/src/lib/tasks.test.ts +++ b/packages/create-app/src/lib/tasks.test.ts @@ -24,7 +24,6 @@ import { buildAppTask, checkAppExistsTask, checkPathExistsTask, - createTemporaryAppFolderTask, moveAppTask, templatingTask, tryInitGitRepository, @@ -163,30 +162,6 @@ describe('tasks', () => { }); }); - describe('createTemporaryAppFolderTask', () => { - it('should create a directory at a given path', async () => { - const tempDir = 'projects/tmpFolder'; - await expect( - createTemporaryAppFolderTask(tempDir), - ).resolves.not.toThrow(); - expect(fs.existsSync(tempDir)).toBe(true); - }); - - it('should fail if a directory of the same name exists', async () => { - const tempDir = 'projects/dir'; - await expect(createTemporaryAppFolderTask(tempDir)).rejects.toThrow( - 'file already exists', - ); - }); - - it('should fail if a file of the same name exists', async () => { - const tempDir = 'projects/dir/my-file.txt'; - await expect(createTemporaryAppFolderTask(tempDir)).rejects.toThrow( - 'file already exists', - ); - }); - }); - describe('buildAppTask', () => { it('should change to `appDir` and run `yarn install` and `yarn tsc`', async () => { const mockChdir = jest.spyOn(process, 'chdir'); diff --git a/packages/create-app/src/lib/tasks.ts b/packages/create-app/src/lib/tasks.ts index 1943b0c3cc..90e6f6ae53 100644 --- a/packages/create-app/src/lib/tasks.ts +++ b/packages/create-app/src/lib/tasks.ts @@ -178,22 +178,6 @@ export async function checkPathExistsTask(path: string) { }); } -/** - * Create a folder to store templated files - * - * @param tempDir - target temporary directory - * @throws if `fs.mkdir` fails - */ -export async function createTemporaryAppFolderTask(tempDir: string) { - await Task.forItem('creating', 'temporary directory', async () => { - try { - await fs.mkdir(tempDir); - } catch (error) { - throw new Error(`Failed to create temporary app directory, ${error}`); - } - }); -} - /** * Run `yarn install` and `run tsc` in application directory * From 567e26240534bb7aba4d1dd1e47d1e385fb8f256 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Tue, 26 Sep 2023 14:18:06 +0200 Subject: [PATCH 077/110] chore: remove redundant resolvePath Signed-off-by: Johan Haals --- packages/create-app/src/createApp.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/create-app/src/createApp.ts b/packages/create-app/src/createApp.ts index bfa53f03c0..09cede933d 100644 --- a/packages/create-app/src/createApp.ts +++ b/packages/create-app/src/createApp.ts @@ -98,9 +98,7 @@ export default async (opts: OptionValues): Promise => { await checkAppExistsTask(paths.targetDir, answers.name); Task.section('Creating a temporary app directory'); - const tempDir = await fs.mkdtemp( - resolvePath(resolvePath(os.tmpdir(), answers.name)), - ); + const tempDir = await fs.mkdtemp(resolvePath(os.tmpdir(), answers.name)); Task.section('Preparing files'); await templatingTask(templateDir, tempDir, { From 68158034e84a0153379e56df60969ce8e6d7c578 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 26 Sep 2023 14:35:40 +0200 Subject: [PATCH 078/110] cli: use file URL for esm loader Signed-off-by: Patrik Oldsberg --- .changeset/four-onions-clap.md | 5 +++++ .../cli/src/lib/experimental/startBackendExperimental.ts | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 .changeset/four-onions-clap.md diff --git a/.changeset/four-onions-clap.md b/.changeset/four-onions-clap.md new file mode 100644 index 0000000000..44d0cf9ae7 --- /dev/null +++ b/.changeset/four-onions-clap.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Fix for the new backend `start` command to make it work on Windows. diff --git a/packages/cli/src/lib/experimental/startBackendExperimental.ts b/packages/cli/src/lib/experimental/startBackendExperimental.ts index 3bc603a9da..1272ba9e66 100644 --- a/packages/cli/src/lib/experimental/startBackendExperimental.ts +++ b/packages/cli/src/lib/experimental/startBackendExperimental.ts @@ -21,7 +21,7 @@ import type { ChildProcess } from 'child_process'; import { IpcServer } from './IpcServer'; import { ServerDataStore } from './ServerDataStore'; import debounce from 'lodash/debounce'; -import { fileURLToPath } from 'url'; +import { fileURLToPath, pathToFileURL } from 'url'; import { isAbsolute as isAbsolutePath } from 'path'; import { paths } from '../paths'; import spawn from 'cross-spawn'; @@ -30,7 +30,7 @@ const loaderArgs = [ '--require', require.resolve('@esbuild-kit/cjs-loader'), '--loader', - require.resolve('@esbuild-kit/esm-loader'), + pathToFileURL(require.resolve('@esbuild-kit/esm-loader')).toString(), // Windows prefers a URL here ]; export async function startBackendExperimental(options: BackendServeOptions) { From bea36177129a4e37c6d5de032266ed5d136b437f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 26 Sep 2023 13:20:00 +0000 Subject: [PATCH 079/110] Version Packages (next) --- .changeset/pre.json | 51 +- docs/releases/v1.19.0-next.0-changelog.md | 2868 +++++++++++++++++ package.json | 2 +- packages/app-defaults/CHANGELOG.md | 11 + packages/app-defaults/package.json | 2 +- packages/app-next-example-plugin/CHANGELOG.md | 8 + packages/app-next-example-plugin/package.json | 2 +- packages/app-next/CHANGELOG.md | 77 + packages/app-next/package.json | 2 +- packages/app/CHANGELOG.md | 76 + packages/app/package.json | 2 +- packages/backend-app-api/CHANGELOG.md | 17 + packages/backend-app-api/package.json | 2 +- packages/backend-common/CHANGELOG.md | 17 + packages/backend-common/package.json | 2 +- packages/backend-defaults/CHANGELOG.md | 9 + packages/backend-defaults/package.json | 2 +- packages/backend-next/CHANGELOG.md | 37 + packages/backend-next/package.json | 2 +- packages/backend-plugin-api/CHANGELOG.md | 11 + packages/backend-plugin-api/package.json | 2 +- packages/backend-plugin-manager/CHANGELOG.md | 23 + packages/backend-plugin-manager/package.json | 2 +- packages/backend-tasks/CHANGELOG.md | 10 + packages/backend-tasks/package.json | 2 +- packages/backend-test-utils/CHANGELOG.md | 13 + packages/backend-test-utils/package.json | 2 +- packages/backend/CHANGELOG.md | 59 + packages/backend/package.json | 2 +- packages/cli-common/CHANGELOG.md | 6 + packages/cli-common/package.json | 2 +- packages/cli-node/CHANGELOG.md | 9 + packages/cli-node/package.json | 2 +- packages/cli/CHANGELOG.md | 26 + packages/cli/package.json | 2 +- packages/codemods/CHANGELOG.md | 8 + packages/codemods/package.json | 2 +- packages/config-loader/CHANGELOG.md | 11 + packages/config-loader/package.json | 2 +- packages/core-app-api/CHANGELOG.md | 10 + packages/core-app-api/package.json | 2 +- packages/core-components/CHANGELOG.md | 14 + packages/core-components/package.json | 2 +- packages/core-plugin-api/CHANGELOG.md | 13 + packages/core-plugin-api/package.json | 2 +- packages/create-app/CHANGELOG.md | 25 + packages/create-app/package.json | 2 +- packages/dev-utils/CHANGELOG.md | 15 + packages/dev-utils/package.json | 2 +- packages/e2e-test-utils/CHANGELOG.md | 7 + packages/e2e-test-utils/package.json | 2 +- packages/e2e-test/CHANGELOG.md | 9 + packages/e2e-test/package.json | 2 +- packages/frontend-app-api/CHANGELOG.md | 19 + packages/frontend-app-api/package.json | 2 +- packages/frontend-plugin-api/CHANGELOG.md | 8 + packages/frontend-plugin-api/package.json | 2 +- packages/integration-react/CHANGELOG.md | 11 + packages/integration-react/package.json | 2 +- packages/integration/CHANGELOG.md | 9 + packages/integration/package.json | 2 +- packages/repo-tools/CHANGELOG.md | 11 + packages/repo-tools/package.json | 2 +- .../techdocs-cli-embedded-app/CHANGELOG.md | 19 + .../techdocs-cli-embedded-app/package.json | 2 +- packages/techdocs-cli/CHANGELOG.md | 13 + packages/techdocs-cli/package.json | 2 +- packages/test-utils/CHANGELOG.md | 14 + packages/test-utils/package.json | 2 +- plugins/adr-backend/CHANGELOG.md | 15 + plugins/adr-backend/package.json | 2 +- plugins/adr-common/CHANGELOG.md | 9 + plugins/adr-common/package.json | 2 +- plugins/adr/CHANGELOG.md | 15 + plugins/adr/package.json | 2 +- plugins/airbrake-backend/CHANGELOG.md | 9 + plugins/airbrake-backend/package.json | 2 +- plugins/airbrake/CHANGELOG.md | 13 + plugins/airbrake/package.json | 2 +- plugins/allure/CHANGELOG.md | 11 + plugins/allure/package.json | 2 +- plugins/analytics-module-ga/CHANGELOG.md | 10 + plugins/analytics-module-ga/package.json | 2 +- plugins/analytics-module-ga4/CHANGELOG.md | 10 + plugins/analytics-module-ga4/package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- plugins/apache-airflow/CHANGELOG.md | 8 + plugins/apache-airflow/package.json | 2 +- plugins/api-docs/CHANGELOG.md | 14 + plugins/api-docs/package.json | 2 +- plugins/apollo-explorer/CHANGELOG.md | 9 + plugins/apollo-explorer/package.json | 2 +- plugins/app-backend/CHANGELOG.md | 12 + plugins/app-backend/package.json | 2 +- plugins/app-node/CHANGELOG.md | 7 + plugins/app-node/package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- .../CHANGELOG.md | 8 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- plugins/auth-backend/CHANGELOG.md | 20 + plugins/auth-backend/package.json | 2 +- plugins/auth-node/CHANGELOG.md | 14 + plugins/auth-node/package.json | 2 +- plugins/azure-devops-backend/CHANGELOG.md | 10 + plugins/azure-devops-backend/package.json | 2 +- plugins/azure-devops/CHANGELOG.md | 13 + plugins/azure-devops/package.json | 2 +- plugins/azure-sites-backend/CHANGELOG.md | 9 + plugins/azure-sites-backend/package.json | 2 +- plugins/azure-sites/CHANGELOG.md | 12 + plugins/azure-sites/package.json | 2 +- plugins/badges-backend/CHANGELOG.md | 13 + plugins/badges-backend/package.json | 2 +- plugins/badges/CHANGELOG.md | 12 + plugins/badges/package.json | 2 +- plugins/bazaar-backend/CHANGELOG.md | 11 + plugins/bazaar-backend/package.json | 2 +- plugins/bazaar/CHANGELOG.md | 15 + plugins/bazaar/package.json | 2 +- plugins/bitbucket-cloud-common/CHANGELOG.md | 7 + plugins/bitbucket-cloud-common/package.json | 2 +- plugins/bitrise/CHANGELOG.md | 11 + plugins/bitrise/package.json | 2 +- .../catalog-backend-module-aws/CHANGELOG.md | 19 + .../catalog-backend-module-aws/package.json | 2 +- .../catalog-backend-module-azure/CHANGELOG.md | 17 + .../catalog-backend-module-azure/package.json | 2 +- .../CHANGELOG.md | 18 + .../package.json | 2 +- .../CHANGELOG.md | 15 + .../package.json | 2 +- .../CHANGELOG.md | 14 + .../package.json | 2 +- .../catalog-backend-module-gcp/CHANGELOG.md | 12 + .../catalog-backend-module-gcp/package.json | 2 +- .../CHANGELOG.md | 15 + .../package.json | 2 +- .../CHANGELOG.md | 20 + .../package.json | 2 +- .../CHANGELOG.md | 16 + .../package.json | 2 +- .../CHANGELOG.md | 16 + .../package.json | 2 +- .../catalog-backend-module-ldap/CHANGELOG.md | 14 + .../catalog-backend-module-ldap/package.json | 2 +- .../CHANGELOG.md | 14 + .../package.json | 2 +- .../CHANGELOG.md | 14 + .../package.json | 2 +- .../CHANGELOG.md | 15 + .../package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- plugins/catalog-backend/CHANGELOG.md | 31 + plugins/catalog-backend/package.json | 2 +- plugins/catalog-graph/CHANGELOG.md | 13 + plugins/catalog-graph/package.json | 2 +- plugins/catalog-import/CHANGELOG.md | 16 + plugins/catalog-import/package.json | 2 +- plugins/catalog-node/CHANGELOG.md | 12 + plugins/catalog-node/package.json | 2 +- plugins/catalog-react/CHANGELOG.md | 19 + plugins/catalog-react/package.json | 2 +- .../catalog-unprocessed-entities/CHANGELOG.md | 11 + .../catalog-unprocessed-entities/package.json | 2 +- plugins/catalog/CHANGELOG.md | 40 + plugins/catalog/package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- plugins/cicd-statistics/CHANGELOG.md | 9 + plugins/cicd-statistics/package.json | 2 +- plugins/circleci/CHANGELOG.md | 11 + plugins/circleci/package.json | 2 +- plugins/cloudbuild/CHANGELOG.md | 11 + plugins/cloudbuild/package.json | 2 +- plugins/code-climate/CHANGELOG.md | 11 + plugins/code-climate/package.json | 2 +- plugins/code-coverage-backend/CHANGELOG.md | 14 + plugins/code-coverage-backend/package.json | 2 +- plugins/code-coverage/CHANGELOG.md | 14 + plugins/code-coverage/package.json | 2 +- plugins/codescene/CHANGELOG.md | 11 + plugins/codescene/package.json | 2 +- plugins/config-schema/CHANGELOG.md | 12 + plugins/config-schema/package.json | 2 +- plugins/cost-insights/CHANGELOG.md | 14 + plugins/cost-insights/package.json | 2 +- plugins/devtools-backend/CHANGELOG.md | 17 + plugins/devtools-backend/package.json | 2 +- plugins/devtools/CHANGELOG.md | 13 + plugins/devtools/package.json | 2 +- plugins/dynatrace/CHANGELOG.md | 11 + plugins/dynatrace/package.json | 2 +- plugins/entity-feedback-backend/CHANGELOG.md | 13 + plugins/entity-feedback-backend/package.json | 2 +- plugins/entity-feedback/CHANGELOG.md | 13 + plugins/entity-feedback/package.json | 2 +- plugins/entity-validation/CHANGELOG.md | 14 + plugins/entity-validation/package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../events-backend-module-azure/CHANGELOG.md | 8 + .../events-backend-module-azure/package.json | 2 +- .../CHANGELOG.md | 8 + .../package.json | 2 +- .../events-backend-module-gerrit/CHANGELOG.md | 8 + .../events-backend-module-gerrit/package.json | 2 +- .../events-backend-module-github/CHANGELOG.md | 9 + .../events-backend-module-github/package.json | 2 +- .../events-backend-module-gitlab/CHANGELOG.md | 9 + .../events-backend-module-gitlab/package.json | 2 +- .../events-backend-test-utils/CHANGELOG.md | 7 + .../events-backend-test-utils/package.json | 2 +- plugins/events-backend/CHANGELOG.md | 10 + plugins/events-backend/package.json | 2 +- plugins/events-node/CHANGELOG.md | 7 + plugins/events-node/package.json | 2 +- .../example-todo-list-backend/CHANGELOG.md | 11 + .../example-todo-list-backend/package.json | 2 +- plugins/example-todo-list/CHANGELOG.md | 9 + plugins/example-todo-list/package.json | 2 +- plugins/explore-backend/CHANGELOG.md | 12 + plugins/explore-backend/package.json | 2 +- plugins/explore-react/CHANGELOG.md | 8 + plugins/explore-react/package.json | 2 +- plugins/explore/CHANGELOG.md | 16 + plugins/explore/package.json | 2 +- plugins/firehydrant/CHANGELOG.md | 11 + plugins/firehydrant/package.json | 2 +- plugins/fossa/CHANGELOG.md | 12 + plugins/fossa/package.json | 2 +- plugins/gcalendar/CHANGELOG.md | 10 + plugins/gcalendar/package.json | 2 +- plugins/gcp-projects/CHANGELOG.md | 9 + plugins/gcp-projects/package.json | 2 +- plugins/git-release-manager/CHANGELOG.md | 10 + plugins/git-release-manager/package.json | 2 +- plugins/github-actions/CHANGELOG.md | 13 + plugins/github-actions/package.json | 2 +- plugins/github-deployments/CHANGELOG.md | 14 + plugins/github-deployments/package.json | 2 +- plugins/github-issues/CHANGELOG.md | 13 + plugins/github-issues/package.json | 2 +- .../github-pull-requests-board/CHANGELOG.md | 12 + .../github-pull-requests-board/package.json | 2 +- plugins/gitops-profiles/CHANGELOG.md | 10 + plugins/gitops-profiles/package.json | 2 +- plugins/gocd/CHANGELOG.md | 12 + plugins/gocd/package.json | 2 +- plugins/graphiql/CHANGELOG.md | 10 + plugins/graphiql/package.json | 2 +- plugins/graphql-backend/CHANGELOG.md | 9 + plugins/graphql-backend/package.json | 2 +- plugins/graphql-voyager/CHANGELOG.md | 9 + plugins/graphql-voyager/package.json | 2 +- plugins/home-react/CHANGELOG.md | 8 + plugins/home-react/package.json | 2 +- plugins/home/CHANGELOG.md | 13 + plugins/home/package.json | 2 +- plugins/ilert/CHANGELOG.md | 12 + plugins/ilert/package.json | 2 +- plugins/jenkins-backend/CHANGELOG.md | 15 + plugins/jenkins-backend/package.json | 2 +- plugins/jenkins/CHANGELOG.md | 13 + plugins/jenkins/package.json | 2 +- plugins/kafka-backend/CHANGELOG.md | 11 + plugins/kafka-backend/package.json | 2 +- plugins/kafka/CHANGELOG.md | 12 + plugins/kafka/package.json | 2 +- plugins/kubernetes-backend/CHANGELOG.md | 19 + plugins/kubernetes-backend/package.json | 2 +- plugins/kubernetes/CHANGELOG.md | 15 + plugins/kubernetes/package.json | 2 +- plugins/lighthouse-backend/CHANGELOG.md | 15 + plugins/lighthouse-backend/package.json | 2 +- plugins/lighthouse/CHANGELOG.md | 13 + plugins/lighthouse/package.json | 2 +- plugins/linguist-backend/CHANGELOG.md | 17 + plugins/linguist-backend/package.json | 2 +- plugins/linguist/CHANGELOG.md | 13 + plugins/linguist/package.json | 2 +- plugins/microsoft-calendar/CHANGELOG.md | 10 + plugins/microsoft-calendar/package.json | 2 +- plugins/newrelic-dashboard/CHANGELOG.md | 11 + plugins/newrelic-dashboard/package.json | 2 +- plugins/newrelic/CHANGELOG.md | 9 + plugins/newrelic/package.json | 2 +- plugins/nomad-backend/CHANGELOG.md | 9 + plugins/nomad-backend/package.json | 2 +- plugins/nomad/CHANGELOG.md | 12 + plugins/nomad/package.json | 2 +- plugins/octopus-deploy/CHANGELOG.md | 11 + plugins/octopus-deploy/package.json | 2 +- plugins/opencost/CHANGELOG.md | 9 + plugins/opencost/package.json | 2 +- plugins/org-react/CHANGELOG.md | 12 + plugins/org-react/package.json | 2 +- plugins/org/CHANGELOG.md | 11 + plugins/org/package.json | 2 +- plugins/pagerduty/CHANGELOG.md | 14 + plugins/pagerduty/package.json | 2 +- plugins/periskop-backend/CHANGELOG.md | 9 + plugins/periskop-backend/package.json | 2 +- plugins/periskop/CHANGELOG.md | 12 + plugins/periskop/package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- plugins/permission-backend/CHANGELOG.md | 13 + plugins/permission-backend/package.json | 2 +- plugins/permission-node/CHANGELOG.md | 12 + plugins/permission-node/package.json | 2 +- plugins/permission-react/CHANGELOG.md | 9 + plugins/permission-react/package.json | 2 +- plugins/playlist-backend/CHANGELOG.md | 17 + plugins/playlist-backend/package.json | 2 +- plugins/playlist/CHANGELOG.md | 17 + plugins/playlist/package.json | 2 +- plugins/proxy-backend/CHANGELOG.md | 9 + plugins/proxy-backend/package.json | 2 +- plugins/puppetdb/CHANGELOG.md | 12 + plugins/puppetdb/package.json | 2 +- plugins/rollbar-backend/CHANGELOG.md | 9 + plugins/rollbar-backend/package.json | 2 +- plugins/rollbar/CHANGELOG.md | 11 + plugins/rollbar/package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- plugins/scaffolder-backend/CHANGELOG.md | 24 + plugins/scaffolder-backend/package.json | 2 +- plugins/scaffolder-node/CHANGELOG.md | 13 + plugins/scaffolder-node/package.json | 2 +- plugins/scaffolder-react/CHANGELOG.md | 16 + plugins/scaffolder-react/package.json | 2 +- plugins/scaffolder/CHANGELOG.md | 22 + plugins/scaffolder/package.json | 2 +- .../CHANGELOG.md | 18 + .../package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- plugins/search-backend-module-pg/CHANGELOG.md | 11 + plugins/search-backend-module-pg/package.json | 2 +- .../CHANGELOG.md | 18 + .../package.json | 2 +- plugins/search-backend-node/CHANGELOG.md | 13 + plugins/search-backend-node/package.json | 2 +- plugins/search-backend/CHANGELOG.md | 17 + plugins/search-backend/package.json | 2 +- plugins/search-react/CHANGELOG.md | 12 + plugins/search-react/package.json | 2 +- plugins/search/CHANGELOG.md | 17 + plugins/search/package.json | 2 +- plugins/sentry/CHANGELOG.md | 11 + plugins/sentry/package.json | 2 +- plugins/shortcuts/CHANGELOG.md | 10 + plugins/shortcuts/package.json | 2 +- plugins/sonarqube-backend/CHANGELOG.md | 11 + plugins/sonarqube-backend/package.json | 2 +- plugins/sonarqube-react/CHANGELOG.md | 8 + plugins/sonarqube-react/package.json | 2 +- plugins/sonarqube/CHANGELOG.md | 12 + plugins/sonarqube/package.json | 2 +- plugins/splunk-on-call/CHANGELOG.md | 11 + plugins/splunk-on-call/package.json | 2 +- plugins/stack-overflow-backend/CHANGELOG.md | 9 + plugins/stack-overflow-backend/package.json | 2 +- plugins/stack-overflow/CHANGELOG.md | 13 + plugins/stack-overflow/package.json | 2 +- plugins/stackstorm/CHANGELOG.md | 10 + plugins/stackstorm/package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- plugins/tech-insights-backend/CHANGELOG.md | 16 + plugins/tech-insights-backend/package.json | 2 +- plugins/tech-insights-node/CHANGELOG.md | 11 + plugins/tech-insights-node/package.json | 2 +- plugins/tech-insights/CHANGELOG.md | 14 + plugins/tech-insights/package.json | 2 +- plugins/tech-radar/CHANGELOG.md | 11 + plugins/tech-radar/package.json | 2 +- .../techdocs-addons-test-utils/CHANGELOG.md | 16 + .../techdocs-addons-test-utils/package.json | 2 +- plugins/techdocs-backend/CHANGELOG.md | 18 + plugins/techdocs-backend/package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- plugins/techdocs-node/CHANGELOG.md | 13 + plugins/techdocs-node/package.json | 2 +- plugins/techdocs-react/CHANGELOG.md | 11 + plugins/techdocs-react/package.json | 2 +- plugins/techdocs/CHANGELOG.md | 18 + plugins/techdocs/package.json | 2 +- plugins/todo-backend/CHANGELOG.md | 15 + plugins/todo-backend/package.json | 2 +- plugins/todo/CHANGELOG.md | 12 + plugins/todo/package.json | 2 +- plugins/user-settings-backend/CHANGELOG.md | 12 + plugins/user-settings-backend/package.json | 2 +- plugins/user-settings/CHANGELOG.md | 14 + plugins/user-settings/package.json | 2 +- plugins/vault-backend/CHANGELOG.md | 10 + plugins/vault-backend/package.json | 2 +- plugins/vault/CHANGELOG.md | 12 + plugins/vault/package.json | 2 +- plugins/xcmetrics/CHANGELOG.md | 10 + plugins/xcmetrics/package.json | 2 +- yarn.lock | 331 +- 428 files changed, 6269 insertions(+), 271 deletions(-) create mode 100644 docs/releases/v1.19.0-next.0-changelog.md create mode 100644 packages/e2e-test-utils/CHANGELOG.md diff --git a/.changeset/pre.json b/.changeset/pre.json index 63e218f886..46230574ed 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -244,7 +244,54 @@ "@backstage/plugin-user-settings-backend": "0.2.1", "@backstage/plugin-vault": "0.1.19", "@backstage/plugin-vault-backend": "0.3.8", - "@backstage/plugin-xcmetrics": "0.2.43" + "@backstage/plugin-xcmetrics": "0.2.43", + "@backstage/e2e-test-utils": "0.0.0" }, - "changesets": [] + "changesets": [ + "angry-badgers-beg", + "big-spies-beam", + "calm-scissors-rescue", + "chatty-papayas-care", + "clean-forks-love", + "dull-bugs-build", + "dull-dolls-explode", + "dull-experts-kiss", + "dull-laws-camp", + "eighty-actors-type", + "four-jars-protect", + "four-onions-clap", + "fresh-kangaroos-tap", + "gentle-elephants-fold", + "gentle-spies-deny", + "itchy-rabbits-exist", + "large-comics-knock", + "lemon-cups-wait", + "lovely-coins-occur", + "lovely-fans-sniff", + "moody-lobsters-rescue", + "nice-clocks-smash", + "nice-dancers-explain", + "perfect-pumas-protect", + "plenty-llamas-double", + "polite-cooks-perform", + "polite-donuts-fail", + "pretty-apes-sneeze", + "pretty-steaks-serve", + "purple-chefs-wait", + "quick-weeks-explode", + "shy-clouds-reflect", + "silent-years-bake", + "small-pugs-build", + "spotty-badgers-wash", + "stupid-eagles-shave", + "tasty-doors-switch", + "ten-seals-wait", + "thirty-coins-sneeze", + "tiny-garlics-cheer", + "twelve-clouds-design", + "wet-olives-wave", + "wet-timers-chew", + "wild-jobs-greet", + "yellow-rings-invent" + ] } diff --git a/docs/releases/v1.19.0-next.0-changelog.md b/docs/releases/v1.19.0-next.0-changelog.md new file mode 100644 index 0000000000..ed95166757 --- /dev/null +++ b/docs/releases/v1.19.0-next.0-changelog.md @@ -0,0 +1,2868 @@ +# Release v1.19.0-next.0 + +## @backstage/cli@0.23.0-next.0 + +### Minor Changes + +- 7077dbf131: The new backend start command that used to be enabled by setting `EXPERIMENTAL_BACKEND_START` is now the default. To revert to the old behavior, set `LEGACY_BACKEND_START` instead. + + This new command is no longer based on Webpack, but instead uses Node.js loaders to transpile on the fly. Rather than hot reloading modules the entire backend is now restarted on change, but the SQLite database state is still maintained across restarts via a parent process. + +### Patch Changes + +- 68158034e8: Fix for the new backend `start` command to make it work on Windows. +- 21cd3b1b24: Added a template for creating `node-library` packages with `yarn new`. +- de42eebaaf: Bumped dev dependencies `@types/node` and `mock-fs`. +- 3ef18f8c06: Explicitly set `exports: 'named'` for CJS builds, ensuring that they have e.g. `exports["default"] = catalogPlugin;` +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/config-loader@1.5.1-next.0 + - @backstage/cli-common@0.1.13-next.0 + - @backstage/config@1.1.0 + - @backstage/release-manifests@0.0.10 + - @backstage/catalog-model@1.4.2 + - @backstage/cli-node@0.1.5-next.0 + - @backstage/errors@1.2.2 + - @backstage/eslint-plugin@0.1.3 + - @backstage/types@1.1.1 + +## @backstage/core-plugin-api@1.7.0-next.0 + +### Minor Changes + +- 322bbcae24: Removed the exprimental plugin configuration API. The `__experimentalReconfigure()` from the plugin options as well as the `__experimentalConfigure()` method on plugin instances have both been removed. + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.1.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.5 + +## @backstage/e2e-test-utils@0.1.0-next.0 + +### Minor Changes + +- f5b41b27a9: Initial release. + +## @backstage/frontend-app-api@0.2.0-next.0 + +### Minor Changes + +- 9d03dfe5e3: The `createApp` config option has been replaced by a new `configLoader` option. There is now also a `pluginLoader` option that can be used to dynamically load plugins into the app. + +### Patch Changes + +- 322bbcae24: Internal update for removal of experimental plugin configuration API. +- 66d51a4827: Prevents root extension override and duplicated plugin extensions. +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/frontend-plugin-api@0.1.1-next.0 + - @backstage/config@1.1.0 + - @backstage/core-app-api@1.10.1-next.0 + - @backstage/plugin-graphiql@0.2.55-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog@1.14.0-next.0 + +### Minor Changes + +- 28f1ab2e1a: The catalog plugin no longer implements the experimental reconfiguration API. The create button title can now instead be configured using the new experimental internationalization API, via the `catalogTranslationRef` exported at `/alpha`. For example: + + ```ts + import { catalogTranslationRef } from '@backstage/plugin-catalog/alpha'; + + const app = createApp({ + __experimentalTranslations: { + resources: [ + createTranslationMessages({ + ref: catalogTranslationRef, + catalog_page_create_button_title: 'Create Software', + }), + ], + }, + }); + ``` + +- f3561a2935: include owner chip in catalog search result item + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/integration-react@1.1.20-next.0 + - @backstage/plugin-search-react@1.7.1-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-scaffolder-common@1.4.1 + - @backstage/plugin-search-common@1.2.6 + +## @backstage/plugin-catalog-backend@1.14.0-next.0 + +### Minor Changes + +- 78af9433c8: Instrumenting some missing metrics with `OpenTelemetry` + +### Patch Changes + +- 348e8c1cdb: Fixes a bug where eagerly deleted entities did not properly trigger re-stitching of entities that they had relations to. +- b97e9790f0: Internal refactors, laying the foundation for later introducing deferred stitching (see #18062). +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-openapi-utils@0.0.4 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-catalog-node@1.4.6-next.0 + - @backstage/plugin-events-node@0.2.14-next.0 + - @backstage/plugin-permission-common@0.7.8 + - @backstage/plugin-permission-node@0.7.16-next.0 + - @backstage/plugin-scaffolder-common@1.4.1 + - @backstage/plugin-search-backend-module-catalog@0.1.9-next.0 + - @backstage/plugin-search-common@1.2.6 + +## @backstage/app-defaults@1.4.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/core-app-api@1.10.1-next.0 + - @backstage/plugin-permission-react@0.4.16-next.0 + - @backstage/theme@0.4.2 + +## @backstage/backend-app-api@0.5.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/config-loader@1.5.1-next.0 + - @backstage/cli-common@0.1.13-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/cli-node@0.1.5-next.0 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-node@0.7.16-next.0 + +## @backstage/backend-common@0.19.7-next.0 + +### Patch Changes + +- 1c3d6fa2b2: The `useHotCleanup` and `useHotMemoize` helpers are now deprecated, since hot module reloads for backend are being phased out. +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/config-loader@1.5.1-next.0 + - @backstage/cli-common@0.1.13-next.0 + - @backstage/config@1.1.0 + - @backstage/integration-aws-node@0.1.6 + - @backstage/backend-app-api@0.5.5-next.0 + - @backstage/backend-dev-utils@0.1.1 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + +## @backstage/backend-defaults@0.2.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/backend-app-api@0.5.5-next.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + +## @backstage/backend-plugin-api@0.6.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.8 + +## @backstage/backend-tasks@0.5.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + +## @backstage/backend-test-utils@0.2.6-next.0 + +### Patch Changes + +- 5ddc03813e: Remove third type parameter used for `MockInstance`, in order to be compatible with older versions of `@types/jest`. +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-app-api@0.5.5-next.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/types@1.1.1 + +## @backstage/cli-common@0.1.13-next.0 + +### Patch Changes + +- de42eebaaf: Bumped dev dependencies `@types/node` and `mock-fs`. + +## @backstage/cli-node@0.1.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli-common@0.1.13-next.0 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + +## @backstage/codemods@0.1.46-next.0 + +### Patch Changes + +- de42eebaaf: Bumped dev dependencies `@types/node` and `mock-fs`. +- Updated dependencies + - @backstage/cli-common@0.1.13-next.0 + +## @backstage/config-loader@1.5.1-next.0 + +### Patch Changes + +- 773ea341d2: The `FileConfigSource` will now retry file reading after a short delay if it reads an empty file. This is to avoid flakiness during watch mode where change events can trigger before the file content has been written. +- Updated dependencies + - @backstage/cli-common@0.1.13-next.0 + - @backstage/config@1.1.0 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + +## @backstage/core-app-api@1.10.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/config@1.1.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.5 + +## @backstage/core-components@0.13.6-next.0 + +### Patch Changes + +- d19a827ef1: MissingAnnotationEmptyState component can now dynamically generate a YAML example based off the current entity being used. +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/config@1.1.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/version-bridge@1.0.5 + +## @backstage/create-app@0.5.6-next.0 + +### Patch Changes + +- ba6a3b59c1: Removed duplicate `apple-touch-icon` link from `packages/app/public/index.html` that linked to nonexistent icon. + +- c8ec0dea4a: Create unique temp directory for each `create-app` execution. + +- b665f2ce65: Change base node image from node:18-bullseye-slim to node:18-bookworm-slim due to Docker build error on bullseye. + + You can apply these change to your own `Dockerfile` by replacing `node:18-bullseye-slim` with `node:18-bookworm-slim` + +- deed089a3d: Bump `cypress` to fix the end-to-end tests + +- de42eebaaf: Bumped dev dependencies `@types/node` and `mock-fs`. + +- 04a3f65e15: Bump Docker base images to `node:18-bullseye-slim` to fix compatibility issues raised during image build. + + You can apply these change to your own `Dockerfile` by replacing `node:16-bullseye-slim` with `node:18-bullseye-slim` + +- 5eacd5d213: The E2E test setup based on Cypress has been replaced with one based on [Playwright](https://playwright.dev/). Migrating existing apps is not required as this is a standalone setup, only do so if you also want to switch from Cypress to Playwright. + + The scripts to run the E2E tests have been removed from `packages/app/package.json`, as they are now instead run from the root. Instead, a new script has been added to the root `package.json`, `yarn test:e2e`, which runs the E2E tests in development mode, unless `CI` is set in the environment. + + The Playwright setup uses utilities from the new `@backstage/e2e-test-utils` package to find and include all packages in the monorepo that have an `e2e-tests` folder. + +- Updated dependencies + - @backstage/cli-common@0.1.13-next.0 + +## @backstage/dev-utils@1.0.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/test-utils@1.4.4-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/integration-react@1.1.20-next.0 + - @backstage/app-defaults@1.4.4-next.0 + - @backstage/core-app-api@1.10.1-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + +## @backstage/frontend-plugin-api@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/types@1.1.1 + +## @backstage/integration@1.7.1-next.0 + +### Patch Changes + +- 3963d0b885: Ensure that all relevant config fields are properly marked as secret +- Updated dependencies + - @backstage/config@1.1.0 + - @backstage/errors@1.2.2 + +## @backstage/integration-react@1.1.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/config@1.1.0 + - @backstage/theme@0.4.2 + +## @backstage/repo-tools@0.3.5-next.0 + +### Patch Changes + +- de42eebaaf: Bumped dev dependencies `@types/node` and `mock-fs`. +- Updated dependencies + - @backstage/cli-common@0.1.13-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/cli-node@0.1.5-next.0 + - @backstage/errors@1.2.2 + +## @techdocs/cli@1.5.2-next.0 + +### Patch Changes + +- de42eebaaf: Bumped dev dependencies `@types/node` and `mock-fs`. +- 2b6e572051: Restructured tests. +- Updated dependencies + - @backstage/cli-common@0.1.13-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/plugin-techdocs-node@1.8.2-next.0 + - @backstage/config@1.1.0 + - @backstage/catalog-model@1.4.2 + +## @backstage/test-utils@1.4.4-next.0 + +### Patch Changes + +- 322bbcae24: Removed the alpha `MockPluginProvider` export since the plugin configuration API has been removed. +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/config@1.1.0 + - @backstage/core-app-api@1.10.1-next.0 + - @backstage/plugin-permission-react@0.4.16-next.0 + - @backstage/theme@0.4.2 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.8 + +## @backstage/plugin-adr@0.6.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/integration-react@1.1.20-next.0 + - @backstage/plugin-adr-common@0.2.16-next.0 + - @backstage/plugin-search-react@1.7.1-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + - @backstage/plugin-search-common@1.2.6 + +## @backstage/plugin-adr-backend@0.4.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/plugin-adr-common@0.2.16-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/plugin-search-common@1.2.6 + +## @backstage/plugin-adr-common@0.2.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/plugin-search-common@1.2.6 + +## @backstage/plugin-airbrake@0.3.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/test-utils@1.4.4-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/dev-utils@1.0.22-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-airbrake-backend@0.3.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + +## @backstage/plugin-allure@0.1.41-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-analytics-module-ga@0.1.34-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/config@1.1.0 + - @backstage/theme@0.4.2 + +## @backstage/plugin-analytics-module-ga4@0.1.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/config@1.1.0 + - @backstage/theme@0.4.2 + +## @backstage/plugin-analytics-module-newrelic-browser@0.0.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/config@1.1.0 + +## @backstage/plugin-apache-airflow@0.2.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + +## @backstage/plugin-api-docs@0.9.12-next.0 + +### Patch Changes + +- 0117a6b47e: Adding `requestInterceptor` option to `api-docs` and pass it to SwaggerUI. This will enable to configure a proxy or headers to be sent to all the request made through the `Try it out` button on SwaggerUI. +- 18f1756908: added aria-label on api definition button for better a11y. +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/plugin-catalog@1.14.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-apollo-explorer@0.1.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/theme@0.4.2 + +## @backstage/plugin-app-backend@0.3.53-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.5.1-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.5-next.0 + +## @backstage/plugin-app-node@0.1.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.5-next.0 + +## @backstage/plugin-auth-backend@0.19.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-backend-module-github-provider@0.1.2-next.0 + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.1.2-next.0 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.1.2-next.0 + - @backstage/plugin-auth-backend-module-google-provider@0.1.2-next.0 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.1.2-next.0 + - @backstage/plugin-catalog-node@1.4.6-next.0 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-backend-module-github-provider@0.1.2-next.0 + +### Patch Changes + +- 5d32a58b5a: Fixed a bug where the GitHub authenticator did not properly persist granted OAuth scopes. +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + +## @backstage/plugin-auth-backend-module-google-provider@0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + +## @backstage/plugin-auth-node@0.3.2-next.0 + +### Patch Changes + +- 6c2b0793bf: Fix for persisted scopes not being properly restored on sign-in. +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + +## @backstage/plugin-azure-devops@0.3.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/plugin-azure-devops-common@0.3.1 + +## @backstage/plugin-azure-devops-backend@0.4.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/plugin-azure-devops-common@0.3.1 + +## @backstage/plugin-azure-sites@0.1.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + - @backstage/plugin-azure-sites-common@0.1.1 + +## @backstage/plugin-azure-sites-backend@0.1.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/plugin-azure-sites-common@0.1.1 + +## @backstage/plugin-badges@0.2.49-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-badges-backend@0.3.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + +## @backstage/plugin-bazaar@0.2.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/cli@0.23.0-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/plugin-catalog@1.14.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-bazaar-backend@0.3.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/errors@1.2.2 + +## @backstage/plugin-bitbucket-cloud-common@0.2.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + +## @backstage/plugin-bitrise@0.1.52-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-catalog-backend-module-aws@0.2.8-next.0 + +### Patch Changes + +- 890e3b5ad4: Make sure to include the error message when ingestion fails +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/integration-aws-node@0.1.6 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-catalog-node@1.4.6-next.0 + - @backstage/plugin-kubernetes-common@0.6.6 + +## @backstage/plugin-catalog-backend-module-azure@0.1.24-next.0 + +### Patch Changes + +- 890e3b5ad4: Make sure to include the error message when ingestion fails +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-catalog-node@1.4.6-next.0 + +## @backstage/plugin-catalog-backend-module-bitbucket@0.2.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.13-next.0 + - @backstage/config@1.1.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.4.6-next.0 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.1.20-next.0 + +### Patch Changes + +- 890e3b5ad4: Make sure to include the error message when ingestion fails +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.13-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-catalog-node@1.4.6-next.0 + - @backstage/plugin-events-node@0.2.14-next.0 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.1.18-next.0 + +### Patch Changes + +- 890e3b5ad4: Make sure to include the error message when ingestion fails +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/plugin-catalog-node@1.4.6-next.0 + +## @backstage/plugin-catalog-backend-module-gcp@0.1.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/plugin-catalog-node@1.4.6-next.0 + - @backstage/plugin-kubernetes-common@0.6.6 + +## @backstage/plugin-catalog-backend-module-gerrit@0.1.21-next.0 + +### Patch Changes + +- 890e3b5ad4: Make sure to include the error message when ingestion fails +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/plugin-catalog-node@1.4.6-next.0 + +## @backstage/plugin-catalog-backend-module-github@0.4.3-next.0 + +### Patch Changes + +- 890e3b5ad4: Make sure to include the error message when ingestion fails +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/plugin-catalog-backend@1.14.0-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-catalog-node@1.4.6-next.0 + - @backstage/plugin-events-node@0.2.14-next.0 + +## @backstage/plugin-catalog-backend-module-gitlab@0.3.2-next.0 + +### Patch Changes + +- 890e3b5ad4: Make sure to include the error message when ingestion fails +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.4.6-next.0 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.4.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.14.0-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/plugin-catalog-node@1.4.6-next.0 + - @backstage/plugin-events-node@0.2.14-next.0 + - @backstage/plugin-permission-common@0.7.8 + +## @backstage/plugin-catalog-backend-module-ldap@0.5.20-next.0 + +### Patch Changes + +- 890e3b5ad4: Make sure to include the error message when ingestion fails +- Updated dependencies + - @backstage/config@1.1.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-catalog-node@1.4.6-next.0 + +## @backstage/plugin-catalog-backend-module-msgraph@0.5.12-next.0 + +### Patch Changes + +- 890e3b5ad4: Make sure to include the error message when ingestion fails +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-catalog-node@1.4.6-next.0 + +## @backstage/plugin-catalog-backend-module-openapi@0.1.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/plugin-catalog-backend@1.14.0-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/catalog-model@1.4.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-catalog-node@1.4.6-next.0 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.1.10-next.0 + +### Patch Changes + +- 890e3b5ad4: Make sure to include the error message when ingestion fails +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.4.6-next.0 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-catalog-node@1.4.6-next.0 + - @backstage/plugin-scaffolder-common@1.4.1 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.3.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/catalog-model@1.4.2 + +## @backstage/plugin-catalog-graph@0.2.37-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-import@0.10.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/integration-react@1.1.20-next.0 + - @backstage/config@1.1.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/plugin-catalog-common@1.0.16 + +## @backstage/plugin-catalog-node@1.4.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.16 + +## @backstage/plugin-catalog-react@1.8.5-next.0 + +### Patch Changes + +- a402e1dfb9: Fixed an issue causing `EntityPage` to show an error for entities containing special characters +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/plugin-permission-react@0.4.16-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.5 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-permission-common@0.7.8 + +## @backstage/plugin-catalog-unprocessed-entities@0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-cicd-statistics@0.1.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/catalog-model@1.4.2 + +## @backstage/plugin-cicd-statistics-module-gitlab@0.1.21-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/plugin-cicd-statistics@0.1.27-next.0 + - @backstage/catalog-model@1.4.2 + +## @backstage/plugin-circleci@0.3.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-cloudbuild@0.3.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-code-climate@0.1.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-code-coverage@0.2.18-next.0 + +### Patch Changes + +- a468544fa9: Updated layout to improve contrasts and consistency with other plugins +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/config@1.1.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-code-coverage-backend@0.2.19-next.0 + +### Patch Changes + +- 4aa27aa200: Added option to set body size limit +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + +## @backstage/plugin-codescene@0.1.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/config@1.1.0 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-config-schema@0.1.46-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/config@1.1.0 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/types@1.1.1 + +## @backstage/plugin-cost-insights@0.12.14-next.0 + +### Patch Changes + +- 959aa2a09f: The experimental plugin configuration has been removed. The trend line can now instead be hidden by setting `costInsights.hideTrendLine` to `true` in the configuration. +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/config@1.1.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + - @backstage/plugin-cost-insights-common@0.1.2 + +## @backstage/plugin-devtools@0.1.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/plugin-permission-react@0.4.16-next.0 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/types@1.1.1 + - @backstage/plugin-devtools-common@0.1.4 + +## @backstage/plugin-devtools-backend@0.2.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/config-loader@1.5.1-next.0 + - @backstage/cli-common@0.1.13-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-devtools-common@0.1.4 + - @backstage/plugin-permission-common@0.7.8 + - @backstage/plugin-permission-node@0.7.16-next.0 + +## @backstage/plugin-dynatrace@7.0.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-entity-feedback@0.2.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/plugin-entity-feedback-common@0.1.3 + +## @backstage/plugin-entity-feedback-backend@0.2.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/plugin-entity-feedback-common@0.1.3 + +## @backstage/plugin-entity-validation@0.1.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/plugin-catalog-common@1.0.16 + +## @backstage/plugin-events-backend@0.2.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/plugin-events-node@0.2.14-next.0 + +## @backstage/plugin-events-backend-module-aws-sqs@0.2.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.2.14-next.0 + +## @backstage/plugin-events-backend-module-azure@0.1.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/plugin-events-node@0.2.14-next.0 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.1.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/plugin-events-node@0.2.14-next.0 + +## @backstage/plugin-events-backend-module-gerrit@0.1.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/plugin-events-node@0.2.14-next.0 + +## @backstage/plugin-events-backend-module-github@0.1.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/plugin-events-node@0.2.14-next.0 + +## @backstage/plugin-events-backend-module-gitlab@0.1.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/plugin-events-node@0.2.14-next.0 + +## @backstage/plugin-events-backend-test-utils@0.1.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.2.14-next.0 + +## @backstage/plugin-events-node@0.2.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.5-next.0 + +## @backstage/plugin-explore@0.4.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/plugin-explore-react@0.0.32-next.0 + - @backstage/plugin-search-react@1.7.1-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-search-common@1.2.6 + +## @backstage/plugin-explore-backend@0.0.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/types@1.1.1 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-search-backend-module-explore@0.1.9-next.0 + - @backstage/plugin-search-common@1.2.6 + +## @backstage/plugin-explore-react@0.0.32-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/plugin-explore-common@0.0.2 + +## @backstage/plugin-firehydrant@0.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-fossa@0.2.57-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-gcalendar@0.3.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-gcp-projects@0.3.42-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/theme@0.4.2 + +## @backstage/plugin-git-release-manager@0.3.38-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/theme@0.4.2 + +## @backstage/plugin-github-actions@0.6.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/integration-react@1.1.20-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-github-deployments@0.1.56-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/integration-react@1.1.20-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-github-issues@0.2.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-github-pull-requests-board@0.1.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-gitops-profiles@0.3.41-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/config@1.1.0 + - @backstage/theme@0.4.2 + +## @backstage/plugin-gocd@0.1.31-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-graphiql@0.2.55-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/frontend-plugin-api@0.1.1-next.0 + - @backstage/theme@0.4.2 + +## @backstage/plugin-graphql-backend@0.1.43-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/plugin-catalog-graphql@0.3.23 + +## @backstage/plugin-graphql-voyager@0.1.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/theme@0.4.2 + +## @backstage/plugin-home@0.5.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/config@1.1.0 + - @backstage/plugin-home-react@0.1.4-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-home-react@0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + +## @backstage/plugin-ilert@0.2.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-jenkins@0.8.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/plugin-jenkins-common@0.1.19 + +## @backstage/plugin-jenkins-backend@0.2.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/plugin-jenkins-common@0.1.19 + - @backstage/plugin-permission-common@0.7.8 + - @backstage/plugin-permission-node@0.7.16-next.0 + +## @backstage/plugin-kafka@0.3.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/config@1.1.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-kafka-backend@0.3.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + +## @backstage/plugin-kubernetes@0.10.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/config@1.1.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.6.6 + +## @backstage/plugin-kubernetes-backend@0.12.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/integration-aws-node@0.1.6 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.4.6-next.0 + - @backstage/plugin-kubernetes-common@0.6.6 + - @backstage/plugin-permission-common@0.7.8 + - @backstage/plugin-permission-node@0.7.16-next.0 + +## @backstage/plugin-lighthouse@0.4.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/config@1.1.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + - @backstage/plugin-lighthouse-common@0.1.3 + +## @backstage/plugin-lighthouse-backend@0.3.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.4.6-next.0 + - @backstage/plugin-lighthouse-common@0.1.3 + +## @backstage/plugin-linguist@0.1.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/plugin-linguist-common@0.1.2 + +## @backstage/plugin-linguist-backend@0.5.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.4.6-next.0 + - @backstage/plugin-linguist-common@0.1.2 + +## @backstage/plugin-microsoft-calendar@0.1.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-newrelic@0.3.41-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/theme@0.4.2 + +## @backstage/plugin-newrelic-dashboard@0.2.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + +## @backstage/plugin-nomad@0.1.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/config@1.1.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-nomad-backend@0.1.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/errors@1.2.2 + +## @backstage/plugin-octopus-deploy@0.2.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-opencost@0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/theme@0.4.2 + +## @backstage/plugin-org@0.6.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-org-react@0.1.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-pagerduty@0.6.6-next.0 + +### Patch Changes + +- b9ce306814: Minor fix to avoid usage of deprecated prop +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/plugin-home-react@0.1.4-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-periskop@0.1.23-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-periskop-backend@0.2.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + +## @backstage/plugin-permission-backend@0.5.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/errors@1.2.2 + - @backstage/plugin-permission-common@0.7.8 + - @backstage/plugin-permission-node@0.7.16-next.0 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/plugin-permission-common@0.7.8 + - @backstage/plugin-permission-node@0.7.16-next.0 + +## @backstage/plugin-permission-node@0.7.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/errors@1.2.2 + - @backstage/plugin-permission-common@0.7.8 + +## @backstage/plugin-permission-react@0.4.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/config@1.1.0 + - @backstage/plugin-permission-common@0.7.8 + +## @backstage/plugin-playlist@0.1.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/plugin-permission-react@0.4.16-next.0 + - @backstage/plugin-search-react@1.7.1-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-permission-common@0.7.8 + - @backstage/plugin-playlist-common@0.1.10 + +## @backstage/plugin-playlist-backend@0.3.9-next.0 + +### Patch Changes + +- 9e46f5ff49: Added support to the playlist plugin for the new backend +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/plugin-permission-common@0.7.8 + - @backstage/plugin-permission-node@0.7.16-next.0 + - @backstage/plugin-playlist-common@0.1.10 + +## @backstage/plugin-proxy-backend@0.4.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + +## @backstage/plugin-puppetdb@0.1.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-rollbar@0.4.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-rollbar-backend@0.1.50-next.0 + +### Patch Changes + +- 407f4284be: ensure rollbar token is hidden +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + +## @backstage/plugin-scaffolder@1.15.1-next.0 + +### Patch Changes + +- b337d78c3b: fixed issue related template editor fails with multiple templates per file. +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/integration-react@1.1.20-next.0 + - @backstage/plugin-scaffolder-react@1.5.6-next.0 + - @backstage/config@1.1.0 + - @backstage/plugin-permission-react@0.4.16-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-scaffolder-common@1.4.1 + +## @backstage/plugin-scaffolder-backend@1.17.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/plugin-catalog-backend@1.14.0-next.0 + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/plugin-scaffolder-node@0.2.5-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.2-next.0 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-catalog-node@1.4.6-next.0 + - @backstage/plugin-permission-common@0.7.8 + - @backstage/plugin-permission-node@0.7.16-next.0 + - @backstage/plugin-scaffolder-common@1.4.1 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/plugin-scaffolder-node@0.2.5-next.0 + - @backstage/config@1.1.0 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.2.29-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/plugin-scaffolder-node@0.2.5-next.0 + - @backstage/config@1.1.0 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.2.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/plugin-scaffolder-node@0.2.5-next.0 + - @backstage/config@1.1.0 + - @backstage/errors@1.2.2 + +## @backstage/plugin-scaffolder-backend-module-rails@0.4.22-next.0 + +### Patch Changes + +- de42eebaaf: Bumped dev dependencies `@types/node` and `mock-fs`. +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/plugin-scaffolder-node@0.2.5-next.0 + - @backstage/config@1.1.0 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.1.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.2.5-next.0 + - @backstage/config@1.1.0 + - @backstage/errors@1.2.2 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.2.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.2.5-next.0 + - @backstage/config@1.1.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-node@0.2.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.4.1 + +## @backstage/plugin-scaffolder-react@1.5.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.5 + - @backstage/plugin-scaffolder-common@1.4.1 + +## @backstage/plugin-search@1.4.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/config@1.1.0 + - @backstage/plugin-search-react@1.7.1-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.5 + - @backstage/plugin-search-common@1.2.6 + +## @backstage/plugin-search-backend@1.4.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-openapi-utils@0.0.4 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.8 + - @backstage/plugin-permission-node@0.7.16-next.0 + - @backstage/plugin-search-backend-node@1.2.9-next.0 + - @backstage/plugin-search-common@1.2.6 + +## @backstage/plugin-search-backend-module-catalog@0.1.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-catalog-node@1.4.6-next.0 + - @backstage/plugin-permission-common@0.7.8 + - @backstage/plugin-search-backend-node@1.2.9-next.0 + - @backstage/plugin-search-common@1.2.6 + +## @backstage/plugin-search-backend-module-elasticsearch@1.3.8-next.0 + +### Patch Changes + +- 3963d0b885: Ensure that all relevant config fields are properly marked as secret +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/integration-aws-node@0.1.6 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/plugin-search-backend-node@1.2.9-next.0 + - @backstage/plugin-search-common@1.2.6 + +## @backstage/plugin-search-backend-module-explore@0.1.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-search-backend-node@1.2.9-next.0 + - @backstage/plugin-search-common@1.2.6 + +## @backstage/plugin-search-backend-module-pg@0.5.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/plugin-search-backend-node@1.2.9-next.0 + - @backstage/plugin-search-common@1.2.6 + +## @backstage/plugin-search-backend-module-techdocs@0.1.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/plugin-techdocs-node@1.8.2-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-catalog-node@1.4.6-next.0 + - @backstage/plugin-permission-common@0.7.8 + - @backstage/plugin-search-backend-node@1.2.9-next.0 + - @backstage/plugin-search-common@1.2.6 + +## @backstage/plugin-search-backend-node@1.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/errors@1.2.2 + - @backstage/plugin-permission-common@0.7.8 + - @backstage/plugin-search-common@1.2.6 + +## @backstage/plugin-search-react@1.7.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/theme@0.4.2 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.5 + - @backstage/plugin-search-common@1.2.6 + +## @backstage/plugin-sentry@0.5.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-shortcuts@0.3.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/theme@0.4.2 + - @backstage/types@1.1.1 + +## @backstage/plugin-sonarqube@0.7.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + - @backstage/plugin-sonarqube-react@0.1.9-next.0 + +## @backstage/plugin-sonarqube-backend@0.2.7-next.0 + +### Patch Changes + +- a5d592d0ad: Added support for the [new backend system](https://backstage.io/docs/backend-system/) +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/errors@1.2.2 + +## @backstage/plugin-sonarqube-react@0.1.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/catalog-model@1.4.2 + +## @backstage/plugin-splunk-on-call@0.4.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-stack-overflow@0.1.21-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/config@1.1.0 + - @backstage/plugin-home-react@0.1.4-next.0 + - @backstage/plugin-search-react@1.7.1-next.0 + - @backstage/theme@0.4.2 + - @backstage/plugin-search-common@1.2.6 + +## @backstage/plugin-stack-overflow-backend@0.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/plugin-search-common@1.2.6 + +## @backstage/plugin-stackstorm@0.1.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-tech-insights@0.3.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-insights-backend@0.5.19-next.0 + +### Patch Changes + +- cc7dddfa7f: Increase the maximum allowed length of an entity filter for tech insights fact schemas. +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + - @backstage/plugin-tech-insights-node@0.4.11-next.0 + +## @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.37-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/errors@1.2.2 + - @backstage/plugin-tech-insights-common@0.2.12 + - @backstage/plugin-tech-insights-node@0.4.11-next.0 + +## @backstage/plugin-tech-insights-node@0.4.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-radar@0.6.9-next.0 + +### Patch Changes + +- c09d2fa1d6: Added experimental support for the declarative integration. +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/frontend-plugin-api@0.1.1-next.0 + - @backstage/theme@0.4.2 + +## @backstage/plugin-techdocs@1.7.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/integration-react@1.1.20-next.0 + - @backstage/config@1.1.0 + - @backstage/plugin-search-react@1.7.1-next.0 + - @backstage/plugin-techdocs-react@1.1.12-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/plugin-search-common@1.2.6 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/test-utils@1.4.4-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/plugin-catalog@1.14.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/integration-react@1.1.20-next.0 + - @backstage/plugin-techdocs@1.7.1-next.0 + - @backstage/core-app-api@1.10.1-next.0 + - @backstage/plugin-search-react@1.7.1-next.0 + - @backstage/plugin-techdocs-react@1.1.12-next.0 + - @backstage/theme@0.4.2 + +## @backstage/plugin-techdocs-backend@1.7.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/plugin-techdocs-node@1.8.2-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-permission-common@0.7.8 + - @backstage/plugin-search-backend-module-techdocs@0.1.9-next.0 + - @backstage/plugin-search-common@1.2.6 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/integration-react@1.1.20-next.0 + - @backstage/plugin-techdocs-react@1.1.12-next.0 + - @backstage/theme@0.4.2 + +## @backstage/plugin-techdocs-node@1.8.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/integration-aws-node@0.1.6 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/plugin-search-common@1.2.6 + +## @backstage/plugin-techdocs-react@1.1.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/config@1.1.0 + - @backstage/catalog-model@1.4.2 + - @backstage/version-bridge@1.0.5 + +## @backstage/plugin-todo@0.2.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-todo-backend@0.3.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-openapi-utils@0.0.4 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/plugin-catalog-node@1.4.6-next.0 + +## @backstage/plugin-user-settings@0.7.11-next.0 + +### Patch Changes + +- d1b637d005: Fixed a bug where the theme icons would not be colored according to their active state. +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/core-app-api@1.10.1-next.0 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/types@1.1.1 + +## @backstage/plugin-user-settings-backend@0.2.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + +## @backstage/plugin-vault@0.1.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + +## @backstage/plugin-vault-backend@0.3.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/errors@1.2.2 + +## @backstage/plugin-xcmetrics@0.2.44-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + +## example-app@0.2.88-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-app-api@0.2.0-next.0 + - @backstage/plugin-pagerduty@0.6.6-next.0 + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/cli@0.23.0-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/plugin-catalog@1.14.0-next.0 + - @backstage/plugin-scaffolder@1.15.1-next.0 + - @backstage/plugin-tech-radar@0.6.9-next.0 + - @backstage/plugin-user-settings@0.7.11-next.0 + - @backstage/plugin-api-docs@0.9.12-next.0 + - @backstage/plugin-code-coverage@0.2.18-next.0 + - @backstage/plugin-cost-insights@0.12.14-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/integration-react@1.1.20-next.0 + - @backstage/plugin-catalog-import@0.10.1-next.0 + - @backstage/plugin-github-actions@0.6.6-next.0 + - @backstage/plugin-techdocs@1.7.1-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.1-next.0 + - @backstage/plugin-adr@0.6.8-next.0 + - @backstage/plugin-airbrake@0.3.25-next.0 + - @backstage/plugin-azure-devops@0.3.7-next.0 + - @backstage/plugin-azure-sites@0.1.14-next.0 + - @backstage/plugin-badges@0.2.49-next.0 + - @backstage/plugin-catalog-graph@0.2.37-next.0 + - @backstage/plugin-circleci@0.3.25-next.0 + - @backstage/plugin-cloudbuild@0.3.25-next.0 + - @backstage/plugin-dynatrace@7.0.5-next.0 + - @backstage/plugin-entity-feedback@0.2.8-next.0 + - @backstage/plugin-explore@0.4.11-next.0 + - @backstage/plugin-gocd@0.1.31-next.0 + - @backstage/plugin-home@0.5.9-next.0 + - @backstage/plugin-jenkins@0.8.7-next.0 + - @backstage/plugin-kafka@0.3.25-next.0 + - @backstage/plugin-kubernetes@0.10.4-next.0 + - @backstage/plugin-lighthouse@0.4.10-next.0 + - @backstage/plugin-linguist@0.1.10-next.0 + - @backstage/plugin-newrelic-dashboard@0.2.18-next.0 + - @backstage/plugin-nomad@0.1.6-next.0 + - @backstage/plugin-octopus-deploy@0.2.7-next.0 + - @backstage/plugin-org@0.6.15-next.0 + - @backstage/plugin-playlist@0.1.17-next.0 + - @backstage/plugin-puppetdb@0.1.8-next.0 + - @backstage/plugin-rollbar@0.4.25-next.0 + - @backstage/plugin-scaffolder-react@1.5.6-next.0 + - @backstage/plugin-search@1.4.1-next.0 + - @backstage/plugin-sentry@0.5.10-next.0 + - @backstage/plugin-tech-insights@0.3.17-next.0 + - @backstage/plugin-todo@0.2.28-next.0 + - @backstage/app-defaults@1.4.4-next.0 + - @backstage/config@1.1.0 + - @backstage/core-app-api@1.10.1-next.0 + - @backstage/plugin-apache-airflow@0.2.16-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.1.4-next.0 + - @backstage/plugin-devtools@0.1.5-next.0 + - @backstage/plugin-gcalendar@0.3.19-next.0 + - @backstage/plugin-gcp-projects@0.3.42-next.0 + - @backstage/plugin-graphiql@0.2.55-next.0 + - @backstage/plugin-microsoft-calendar@0.1.8-next.0 + - @backstage/plugin-newrelic@0.3.41-next.0 + - @backstage/plugin-permission-react@0.4.16-next.0 + - @backstage/plugin-search-react@1.7.1-next.0 + - @backstage/plugin-shortcuts@0.3.15-next.0 + - @backstage/plugin-stack-overflow@0.1.21-next.0 + - @backstage/plugin-stackstorm@0.1.7-next.0 + - @backstage/plugin-techdocs-react@1.1.12-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-search-common@1.2.6 + +## example-app-next@0.0.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-app-api@0.2.0-next.0 + - @backstage/plugin-pagerduty@0.6.6-next.0 + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/cli@0.23.0-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/plugin-catalog@1.14.0-next.0 + - @backstage/plugin-scaffolder@1.15.1-next.0 + - @backstage/plugin-tech-radar@0.6.9-next.0 + - @backstage/plugin-user-settings@0.7.11-next.0 + - @backstage/plugin-api-docs@0.9.12-next.0 + - @backstage/plugin-code-coverage@0.2.18-next.0 + - @backstage/plugin-cost-insights@0.12.14-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/frontend-plugin-api@0.1.1-next.0 + - @backstage/integration-react@1.1.20-next.0 + - @backstage/plugin-catalog-import@0.10.1-next.0 + - @backstage/plugin-github-actions@0.6.6-next.0 + - @backstage/plugin-techdocs@1.7.1-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.1-next.0 + - @backstage/plugin-adr@0.6.8-next.0 + - @backstage/plugin-airbrake@0.3.25-next.0 + - @backstage/plugin-azure-devops@0.3.7-next.0 + - @backstage/plugin-azure-sites@0.1.14-next.0 + - @backstage/plugin-badges@0.2.49-next.0 + - @backstage/plugin-catalog-graph@0.2.37-next.0 + - @backstage/plugin-circleci@0.3.25-next.0 + - @backstage/plugin-cloudbuild@0.3.25-next.0 + - @backstage/plugin-dynatrace@7.0.5-next.0 + - @backstage/plugin-entity-feedback@0.2.8-next.0 + - @backstage/plugin-explore@0.4.11-next.0 + - @backstage/plugin-gocd@0.1.31-next.0 + - @backstage/plugin-home@0.5.9-next.0 + - @backstage/plugin-jenkins@0.8.7-next.0 + - @backstage/plugin-kafka@0.3.25-next.0 + - @backstage/plugin-kubernetes@0.10.4-next.0 + - @backstage/plugin-lighthouse@0.4.10-next.0 + - @backstage/plugin-linguist@0.1.10-next.0 + - @backstage/plugin-newrelic-dashboard@0.2.18-next.0 + - @backstage/plugin-octopus-deploy@0.2.7-next.0 + - @backstage/plugin-org@0.6.15-next.0 + - @backstage/plugin-playlist@0.1.17-next.0 + - @backstage/plugin-puppetdb@0.1.8-next.0 + - @backstage/plugin-rollbar@0.4.25-next.0 + - @backstage/plugin-scaffolder-react@1.5.6-next.0 + - @backstage/plugin-search@1.4.1-next.0 + - @backstage/plugin-sentry@0.5.10-next.0 + - @backstage/plugin-tech-insights@0.3.17-next.0 + - @backstage/plugin-todo@0.2.28-next.0 + - @backstage/app-defaults@1.4.4-next.0 + - @backstage/config@1.1.0 + - @backstage/core-app-api@1.10.1-next.0 + - @backstage/plugin-apache-airflow@0.2.16-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.1.4-next.0 + - @backstage/plugin-devtools@0.1.5-next.0 + - @backstage/plugin-gcalendar@0.3.19-next.0 + - @backstage/plugin-gcp-projects@0.3.42-next.0 + - @backstage/plugin-graphiql@0.2.55-next.0 + - @backstage/plugin-microsoft-calendar@0.1.8-next.0 + - @backstage/plugin-newrelic@0.3.41-next.0 + - @backstage/plugin-permission-react@0.4.16-next.0 + - @backstage/plugin-search-react@1.7.1-next.0 + - @backstage/plugin-shortcuts@0.3.15-next.0 + - @backstage/plugin-stack-overflow@0.1.21-next.0 + - @backstage/plugin-stackstorm@0.1.7-next.0 + - @backstage/plugin-techdocs-react@1.1.12-next.0 + - app-next-example-plugin@0.0.2-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-search-common@1.2.6 + +## app-next-example-plugin@0.0.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.13.6-next.0 + - @backstage/frontend-plugin-api@0.1.1-next.0 + +## example-backend@0.2.88-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-module-elasticsearch@1.3.8-next.0 + - @backstage/integration@1.7.1-next.0 + - @backstage/plugin-playlist-backend@0.3.9-next.0 + - @backstage/plugin-rollbar-backend@0.1.50-next.0 + - @backstage/plugin-catalog-backend@1.14.0-next.0 + - @backstage/plugin-tech-insights-backend@0.5.19-next.0 + - @backstage/plugin-code-coverage-backend@0.2.19-next.0 + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.22-next.0 + - @backstage/backend-common@0.19.7-next.0 + - example-app@0.2.88-next.0 + - @backstage/plugin-adr-backend@0.4.2-next.0 + - @backstage/plugin-scaffolder-backend@1.17.3-next.0 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.6-next.0 + - @backstage/plugin-techdocs-backend@1.7.2-next.0 + - @backstage/plugin-todo-backend@0.3.3-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/plugin-app-backend@0.3.53-next.0 + - @backstage/plugin-auth-backend@0.19.2-next.0 + - @backstage/plugin-azure-devops-backend@0.4.2-next.0 + - @backstage/plugin-azure-sites-backend@0.1.15-next.0 + - @backstage/plugin-badges-backend@0.3.2-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.2-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.3.2-next.0 + - @backstage/plugin-catalog-node@1.4.6-next.0 + - @backstage/plugin-devtools-backend@0.2.2-next.0 + - @backstage/plugin-entity-feedback-backend@0.2.2-next.0 + - @backstage/plugin-events-backend@0.2.14-next.0 + - @backstage/plugin-events-node@0.2.14-next.0 + - @backstage/plugin-explore-backend@0.0.15-next.0 + - @backstage/plugin-graphql-backend@0.1.43-next.0 + - @backstage/plugin-jenkins-backend@0.2.8-next.0 + - @backstage/plugin-kafka-backend@0.3.2-next.0 + - @backstage/plugin-kubernetes-backend@0.12.2-next.0 + - @backstage/plugin-lighthouse-backend@0.3.2-next.0 + - @backstage/plugin-linguist-backend@0.5.2-next.0 + - @backstage/plugin-nomad-backend@0.1.7-next.0 + - @backstage/plugin-permission-backend@0.5.28-next.0 + - @backstage/plugin-permission-common@0.7.8 + - @backstage/plugin-permission-node@0.7.16-next.0 + - @backstage/plugin-proxy-backend@0.4.2-next.0 + - @backstage/plugin-search-backend@1.4.5-next.0 + - @backstage/plugin-search-backend-module-catalog@0.1.9-next.0 + - @backstage/plugin-search-backend-module-explore@0.1.9-next.0 + - @backstage/plugin-search-backend-module-pg@0.5.14-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.1.9-next.0 + - @backstage/plugin-search-backend-node@1.2.9-next.0 + - @backstage/plugin-search-common@1.2.6 + - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.37-next.0 + - @backstage/plugin-tech-insights-node@0.4.11-next.0 + +## example-backend-next@0.0.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-sonarqube-backend@0.2.7-next.0 + - @backstage/plugin-playlist-backend@0.3.9-next.0 + - @backstage/plugin-catalog-backend@1.14.0-next.0 + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/plugin-adr-backend@0.4.2-next.0 + - @backstage/plugin-scaffolder-backend@1.17.3-next.0 + - @backstage/plugin-techdocs-backend@1.7.2-next.0 + - @backstage/plugin-todo-backend@0.3.3-next.0 + - @backstage/backend-defaults@0.2.5-next.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/plugin-app-backend@0.3.53-next.0 + - @backstage/plugin-azure-devops-backend@0.4.2-next.0 + - @backstage/plugin-badges-backend@0.3.2-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.2-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.3.2-next.0 + - @backstage/plugin-devtools-backend@0.2.2-next.0 + - @backstage/plugin-entity-feedback-backend@0.2.2-next.0 + - @backstage/plugin-kubernetes-backend@0.12.2-next.0 + - @backstage/plugin-lighthouse-backend@0.3.2-next.0 + - @backstage/plugin-linguist-backend@0.5.2-next.0 + - @backstage/plugin-permission-backend@0.5.28-next.0 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.1.2-next.0 + - @backstage/plugin-permission-common@0.7.8 + - @backstage/plugin-permission-node@0.7.16-next.0 + - @backstage/plugin-proxy-backend@0.4.2-next.0 + - @backstage/plugin-search-backend@1.4.5-next.0 + - @backstage/plugin-search-backend-module-catalog@0.1.9-next.0 + - @backstage/plugin-search-backend-module-explore@0.1.9-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.1.9-next.0 + - @backstage/plugin-search-backend-node@1.2.9-next.0 + +## @backstage/backend-plugin-manager@0.0.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.14.0-next.0 + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/cli-common@0.1.13-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/plugin-scaffolder-node@0.2.5-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/cli-node@0.1.5-next.0 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-events-backend@0.2.14-next.0 + - @backstage/plugin-events-node@0.2.14-next.0 + - @backstage/plugin-permission-common@0.7.8 + - @backstage/plugin-permission-node@0.7.16-next.0 + - @backstage/plugin-search-backend-node@1.2.9-next.0 + - @backstage/plugin-search-common@1.2.6 + +## e2e-test@0.2.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.6-next.0 + - @backstage/cli-common@0.1.13-next.0 + - @backstage/errors@1.2.2 + +## techdocs-cli-embedded-app@0.2.87-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/test-utils@1.4.4-next.0 + - @backstage/cli@0.23.0-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/plugin-catalog@1.14.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/integration-react@1.1.20-next.0 + - @backstage/plugin-techdocs@1.7.1-next.0 + - @backstage/app-defaults@1.4.4-next.0 + - @backstage/config@1.1.0 + - @backstage/core-app-api@1.10.1-next.0 + - @backstage/plugin-techdocs-react@1.1.12-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + +## @internal/plugin-todo-list@1.0.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/theme@0.4.2 + +## @internal/plugin-todo-list-backend@1.0.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/errors@1.2.2 diff --git a/package.json b/package.json index f027658ffd..c3b047c8c1 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "@types/react-dom": "^17", "mock-fs@^5.2.0": "patch:mock-fs@npm%3A5.2.0#./.yarn/patches/mock-fs-npm-5.2.0-5103a7b507.patch" }, - "version": "1.18.0", + "version": "1.19.0-next.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 1cf56c16cd..4b37388ccd 100644 --- a/packages/app-defaults/CHANGELOG.md +++ b/packages/app-defaults/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/app-defaults +## 1.4.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/core-app-api@1.10.1-next.0 + - @backstage/plugin-permission-react@0.4.16-next.0 + - @backstage/theme@0.4.2 + ## 1.4.3 ### Patch Changes diff --git a/packages/app-defaults/package.json b/packages/app-defaults/package.json index d18ade17a1..4a4578c94d 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.4.3", + "version": "1.4.4-next.0", "publishConfig": { "access": "public", "main": "dist/index.esm.js", diff --git a/packages/app-next-example-plugin/CHANGELOG.md b/packages/app-next-example-plugin/CHANGELOG.md index e833efee8b..03e627520d 100644 --- a/packages/app-next-example-plugin/CHANGELOG.md +++ b/packages/app-next-example-plugin/CHANGELOG.md @@ -1,5 +1,13 @@ # app-next-example-plugin +## 0.0.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.13.6-next.0 + - @backstage/frontend-plugin-api@0.1.1-next.0 + ## 0.0.1 ### Patch Changes diff --git a/packages/app-next-example-plugin/package.json b/packages/app-next-example-plugin/package.json index 5d86099d2a..300db8d39a 100644 --- a/packages/app-next-example-plugin/package.json +++ b/packages/app-next-example-plugin/package.json @@ -1,7 +1,7 @@ { "name": "app-next-example-plugin", "description": "Backstage internal example plugin", - "version": "0.0.1", + "version": "0.0.2-next.0", "publishConfig": { "access": "public", "main": "dist/index.esm.js", diff --git a/packages/app-next/CHANGELOG.md b/packages/app-next/CHANGELOG.md index f6e8142480..b70579bbed 100644 --- a/packages/app-next/CHANGELOG.md +++ b/packages/app-next/CHANGELOG.md @@ -1,5 +1,82 @@ # example-app-next +## 0.0.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-app-api@0.2.0-next.0 + - @backstage/plugin-pagerduty@0.6.6-next.0 + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/cli@0.23.0-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/plugin-catalog@1.14.0-next.0 + - @backstage/plugin-scaffolder@1.15.1-next.0 + - @backstage/plugin-tech-radar@0.6.9-next.0 + - @backstage/plugin-user-settings@0.7.11-next.0 + - @backstage/plugin-api-docs@0.9.12-next.0 + - @backstage/plugin-code-coverage@0.2.18-next.0 + - @backstage/plugin-cost-insights@0.12.14-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/frontend-plugin-api@0.1.1-next.0 + - @backstage/integration-react@1.1.20-next.0 + - @backstage/plugin-catalog-import@0.10.1-next.0 + - @backstage/plugin-github-actions@0.6.6-next.0 + - @backstage/plugin-techdocs@1.7.1-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.1-next.0 + - @backstage/plugin-adr@0.6.8-next.0 + - @backstage/plugin-airbrake@0.3.25-next.0 + - @backstage/plugin-azure-devops@0.3.7-next.0 + - @backstage/plugin-azure-sites@0.1.14-next.0 + - @backstage/plugin-badges@0.2.49-next.0 + - @backstage/plugin-catalog-graph@0.2.37-next.0 + - @backstage/plugin-circleci@0.3.25-next.0 + - @backstage/plugin-cloudbuild@0.3.25-next.0 + - @backstage/plugin-dynatrace@7.0.5-next.0 + - @backstage/plugin-entity-feedback@0.2.8-next.0 + - @backstage/plugin-explore@0.4.11-next.0 + - @backstage/plugin-gocd@0.1.31-next.0 + - @backstage/plugin-home@0.5.9-next.0 + - @backstage/plugin-jenkins@0.8.7-next.0 + - @backstage/plugin-kafka@0.3.25-next.0 + - @backstage/plugin-kubernetes@0.10.4-next.0 + - @backstage/plugin-lighthouse@0.4.10-next.0 + - @backstage/plugin-linguist@0.1.10-next.0 + - @backstage/plugin-newrelic-dashboard@0.2.18-next.0 + - @backstage/plugin-octopus-deploy@0.2.7-next.0 + - @backstage/plugin-org@0.6.15-next.0 + - @backstage/plugin-playlist@0.1.17-next.0 + - @backstage/plugin-puppetdb@0.1.8-next.0 + - @backstage/plugin-rollbar@0.4.25-next.0 + - @backstage/plugin-scaffolder-react@1.5.6-next.0 + - @backstage/plugin-search@1.4.1-next.0 + - @backstage/plugin-sentry@0.5.10-next.0 + - @backstage/plugin-tech-insights@0.3.17-next.0 + - @backstage/plugin-todo@0.2.28-next.0 + - @backstage/app-defaults@1.4.4-next.0 + - @backstage/config@1.1.0 + - @backstage/core-app-api@1.10.1-next.0 + - @backstage/plugin-apache-airflow@0.2.16-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.1.4-next.0 + - @backstage/plugin-devtools@0.1.5-next.0 + - @backstage/plugin-gcalendar@0.3.19-next.0 + - @backstage/plugin-gcp-projects@0.3.42-next.0 + - @backstage/plugin-graphiql@0.2.55-next.0 + - @backstage/plugin-microsoft-calendar@0.1.8-next.0 + - @backstage/plugin-newrelic@0.3.41-next.0 + - @backstage/plugin-permission-react@0.4.16-next.0 + - @backstage/plugin-search-react@1.7.1-next.0 + - @backstage/plugin-shortcuts@0.3.15-next.0 + - @backstage/plugin-stack-overflow@0.1.21-next.0 + - @backstage/plugin-stackstorm@0.1.7-next.0 + - @backstage/plugin-techdocs-react@1.1.12-next.0 + - app-next-example-plugin@0.0.2-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-search-common@1.2.6 + ## 0.0.1 ### Patch Changes diff --git a/packages/app-next/package.json b/packages/app-next/package.json index 4f94bb21e5..40e7d75c1e 100644 --- a/packages/app-next/package.json +++ b/packages/app-next/package.json @@ -1,6 +1,6 @@ { "name": "example-app-next", - "version": "0.0.1", + "version": "0.0.2-next.0", "private": true, "backstage": { "role": "frontend" diff --git a/packages/app/CHANGELOG.md b/packages/app/CHANGELOG.md index 9d232123db..9fe80276a6 100644 --- a/packages/app/CHANGELOG.md +++ b/packages/app/CHANGELOG.md @@ -1,5 +1,81 @@ # example-app +## 0.2.88-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-app-api@0.2.0-next.0 + - @backstage/plugin-pagerduty@0.6.6-next.0 + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/cli@0.23.0-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/plugin-catalog@1.14.0-next.0 + - @backstage/plugin-scaffolder@1.15.1-next.0 + - @backstage/plugin-tech-radar@0.6.9-next.0 + - @backstage/plugin-user-settings@0.7.11-next.0 + - @backstage/plugin-api-docs@0.9.12-next.0 + - @backstage/plugin-code-coverage@0.2.18-next.0 + - @backstage/plugin-cost-insights@0.12.14-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/integration-react@1.1.20-next.0 + - @backstage/plugin-catalog-import@0.10.1-next.0 + - @backstage/plugin-github-actions@0.6.6-next.0 + - @backstage/plugin-techdocs@1.7.1-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.1-next.0 + - @backstage/plugin-adr@0.6.8-next.0 + - @backstage/plugin-airbrake@0.3.25-next.0 + - @backstage/plugin-azure-devops@0.3.7-next.0 + - @backstage/plugin-azure-sites@0.1.14-next.0 + - @backstage/plugin-badges@0.2.49-next.0 + - @backstage/plugin-catalog-graph@0.2.37-next.0 + - @backstage/plugin-circleci@0.3.25-next.0 + - @backstage/plugin-cloudbuild@0.3.25-next.0 + - @backstage/plugin-dynatrace@7.0.5-next.0 + - @backstage/plugin-entity-feedback@0.2.8-next.0 + - @backstage/plugin-explore@0.4.11-next.0 + - @backstage/plugin-gocd@0.1.31-next.0 + - @backstage/plugin-home@0.5.9-next.0 + - @backstage/plugin-jenkins@0.8.7-next.0 + - @backstage/plugin-kafka@0.3.25-next.0 + - @backstage/plugin-kubernetes@0.10.4-next.0 + - @backstage/plugin-lighthouse@0.4.10-next.0 + - @backstage/plugin-linguist@0.1.10-next.0 + - @backstage/plugin-newrelic-dashboard@0.2.18-next.0 + - @backstage/plugin-nomad@0.1.6-next.0 + - @backstage/plugin-octopus-deploy@0.2.7-next.0 + - @backstage/plugin-org@0.6.15-next.0 + - @backstage/plugin-playlist@0.1.17-next.0 + - @backstage/plugin-puppetdb@0.1.8-next.0 + - @backstage/plugin-rollbar@0.4.25-next.0 + - @backstage/plugin-scaffolder-react@1.5.6-next.0 + - @backstage/plugin-search@1.4.1-next.0 + - @backstage/plugin-sentry@0.5.10-next.0 + - @backstage/plugin-tech-insights@0.3.17-next.0 + - @backstage/plugin-todo@0.2.28-next.0 + - @backstage/app-defaults@1.4.4-next.0 + - @backstage/config@1.1.0 + - @backstage/core-app-api@1.10.1-next.0 + - @backstage/plugin-apache-airflow@0.2.16-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.1.4-next.0 + - @backstage/plugin-devtools@0.1.5-next.0 + - @backstage/plugin-gcalendar@0.3.19-next.0 + - @backstage/plugin-gcp-projects@0.3.42-next.0 + - @backstage/plugin-graphiql@0.2.55-next.0 + - @backstage/plugin-microsoft-calendar@0.1.8-next.0 + - @backstage/plugin-newrelic@0.3.41-next.0 + - @backstage/plugin-permission-react@0.4.16-next.0 + - @backstage/plugin-search-react@1.7.1-next.0 + - @backstage/plugin-shortcuts@0.3.15-next.0 + - @backstage/plugin-stack-overflow@0.1.21-next.0 + - @backstage/plugin-stackstorm@0.1.7-next.0 + - @backstage/plugin-techdocs-react@1.1.12-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-search-common@1.2.6 + ## 0.2.87 ### Patch Changes diff --git a/packages/app/package.json b/packages/app/package.json index 0c4037b8cd..5b17cc349e 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "example-app", - "version": "0.2.87", + "version": "0.2.88-next.0", "private": true, "backstage": { "role": "frontend" diff --git a/packages/backend-app-api/CHANGELOG.md b/packages/backend-app-api/CHANGELOG.md index 3d7864d95c..e70c14d84e 100644 --- a/packages/backend-app-api/CHANGELOG.md +++ b/packages/backend-app-api/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/backend-app-api +## 0.5.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/config-loader@1.5.1-next.0 + - @backstage/cli-common@0.1.13-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/cli-node@0.1.5-next.0 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-node@0.7.16-next.0 + ## 0.5.3 ### Patch Changes diff --git a/packages/backend-app-api/package.json b/packages/backend-app-api/package.json index 0881be4ca8..d29b00d036 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.5.3", + "version": "0.5.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-common/CHANGELOG.md b/packages/backend-common/CHANGELOG.md index 66b9600222..6e761caa41 100644 --- a/packages/backend-common/CHANGELOG.md +++ b/packages/backend-common/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/backend-common +## 0.19.7-next.0 + +### Patch Changes + +- 1c3d6fa2b2: The `useHotCleanup` and `useHotMemoize` helpers are now deprecated, since hot module reloads for backend are being phased out. +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/config-loader@1.5.1-next.0 + - @backstage/cli-common@0.1.13-next.0 + - @backstage/config@1.1.0 + - @backstage/integration-aws-node@0.1.6 + - @backstage/backend-app-api@0.5.5-next.0 + - @backstage/backend-dev-utils@0.1.1 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + ## 0.19.5 ### Patch Changes diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json index a1487163b2..a887bdc8e7 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.19.5", + "version": "0.19.7-next.0", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-defaults/CHANGELOG.md b/packages/backend-defaults/CHANGELOG.md index b70db2e92d..98f39ef7b6 100644 --- a/packages/backend-defaults/CHANGELOG.md +++ b/packages/backend-defaults/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/backend-defaults +## 0.2.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/backend-app-api@0.5.5-next.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + ## 0.2.3 ### Patch Changes diff --git a/packages/backend-defaults/package.json b/packages/backend-defaults/package.json index cff7d00bb9..3aee2f5708 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.2.3", + "version": "0.2.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-next/CHANGELOG.md b/packages/backend-next/CHANGELOG.md index ab19eee8d9..92a7b57513 100644 --- a/packages/backend-next/CHANGELOG.md +++ b/packages/backend-next/CHANGELOG.md @@ -1,5 +1,42 @@ # example-backend-next +## 0.0.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-sonarqube-backend@0.2.7-next.0 + - @backstage/plugin-playlist-backend@0.3.9-next.0 + - @backstage/plugin-catalog-backend@1.14.0-next.0 + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/plugin-adr-backend@0.4.2-next.0 + - @backstage/plugin-scaffolder-backend@1.17.3-next.0 + - @backstage/plugin-techdocs-backend@1.7.2-next.0 + - @backstage/plugin-todo-backend@0.3.3-next.0 + - @backstage/backend-defaults@0.2.5-next.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/plugin-app-backend@0.3.53-next.0 + - @backstage/plugin-azure-devops-backend@0.4.2-next.0 + - @backstage/plugin-badges-backend@0.3.2-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.2-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.3.2-next.0 + - @backstage/plugin-devtools-backend@0.2.2-next.0 + - @backstage/plugin-entity-feedback-backend@0.2.2-next.0 + - @backstage/plugin-kubernetes-backend@0.12.2-next.0 + - @backstage/plugin-lighthouse-backend@0.3.2-next.0 + - @backstage/plugin-linguist-backend@0.5.2-next.0 + - @backstage/plugin-permission-backend@0.5.28-next.0 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.1.2-next.0 + - @backstage/plugin-permission-common@0.7.8 + - @backstage/plugin-permission-node@0.7.16-next.0 + - @backstage/plugin-proxy-backend@0.4.2-next.0 + - @backstage/plugin-search-backend@1.4.5-next.0 + - @backstage/plugin-search-backend-module-catalog@0.1.9-next.0 + - @backstage/plugin-search-backend-module-explore@0.1.9-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.1.9-next.0 + - @backstage/plugin-search-backend-node@1.2.9-next.0 + ## 0.0.15 ### Patch Changes diff --git a/packages/backend-next/package.json b/packages/backend-next/package.json index 6ea511a17b..9e2dc78bfd 100644 --- a/packages/backend-next/package.json +++ b/packages/backend-next/package.json @@ -1,6 +1,6 @@ { "name": "example-backend-next", - "version": "0.0.15", + "version": "0.0.16-next.0", "main": "dist/index.cjs.js", "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 5f78bb435d..684df46db9 100644 --- a/packages/backend-plugin-api/CHANGELOG.md +++ b/packages/backend-plugin-api/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/backend-plugin-api +## 0.6.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.8 + ## 0.6.3 ### Patch Changes diff --git a/packages/backend-plugin-api/package.json b/packages/backend-plugin-api/package.json index 9ca71972e1..b0da3fc80a 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.6.3", + "version": "0.6.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-plugin-manager/CHANGELOG.md b/packages/backend-plugin-manager/CHANGELOG.md index 71443041d2..bbf909d421 100644 --- a/packages/backend-plugin-manager/CHANGELOG.md +++ b/packages/backend-plugin-manager/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/backend-plugin-manager +## 0.0.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.14.0-next.0 + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/cli-common@0.1.13-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/plugin-scaffolder-node@0.2.5-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/cli-node@0.1.5-next.0 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-events-backend@0.2.14-next.0 + - @backstage/plugin-events-node@0.2.14-next.0 + - @backstage/plugin-permission-common@0.7.8 + - @backstage/plugin-permission-node@0.7.16-next.0 + - @backstage/plugin-search-backend-node@1.2.9-next.0 + - @backstage/plugin-search-common@1.2.6 + ## 0.0.1 ### Patch Changes diff --git a/packages/backend-plugin-manager/package.json b/packages/backend-plugin-manager/package.json index e4d737a328..acf15928b0 100644 --- a/packages/backend-plugin-manager/package.json +++ b/packages/backend-plugin-manager/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-plugin-manager", "description": "Backstage plugin management backend", - "version": "0.0.1", + "version": "0.0.2-next.0", "private": true, "main": "src/index.ts", "types": "src/index.ts", diff --git a/packages/backend-tasks/CHANGELOG.md b/packages/backend-tasks/CHANGELOG.md index efcfa0c702..d8a7cc3754 100644 --- a/packages/backend-tasks/CHANGELOG.md +++ b/packages/backend-tasks/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/backend-tasks +## 0.5.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + ## 0.5.8 ### Patch Changes diff --git a/packages/backend-tasks/package.json b/packages/backend-tasks/package.json index a8d52d0b00..f4118b8098 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.8", + "version": "0.5.10-next.0", "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 a725f8037b..ba53fae7f7 100644 --- a/packages/backend-test-utils/CHANGELOG.md +++ b/packages/backend-test-utils/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/backend-test-utils +## 0.2.6-next.0 + +### Patch Changes + +- 5ddc03813e: Remove third type parameter used for `MockInstance`, in order to be compatible with older versions of `@types/jest`. +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-app-api@0.5.5-next.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/types@1.1.1 + ## 0.2.3 ### Patch Changes diff --git a/packages/backend-test-utils/package.json b/packages/backend-test-utils/package.json index 8777439e64..5274b49ce2 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.2.3", + "version": "0.2.6-next.0", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend/CHANGELOG.md b/packages/backend/CHANGELOG.md index 880eb33270..5d89212a42 100644 --- a/packages/backend/CHANGELOG.md +++ b/packages/backend/CHANGELOG.md @@ -1,5 +1,64 @@ # example-backend +## 0.2.88-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-module-elasticsearch@1.3.8-next.0 + - @backstage/integration@1.7.1-next.0 + - @backstage/plugin-playlist-backend@0.3.9-next.0 + - @backstage/plugin-rollbar-backend@0.1.50-next.0 + - @backstage/plugin-catalog-backend@1.14.0-next.0 + - @backstage/plugin-tech-insights-backend@0.5.19-next.0 + - @backstage/plugin-code-coverage-backend@0.2.19-next.0 + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.22-next.0 + - @backstage/backend-common@0.19.7-next.0 + - example-app@0.2.88-next.0 + - @backstage/plugin-adr-backend@0.4.2-next.0 + - @backstage/plugin-scaffolder-backend@1.17.3-next.0 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.6-next.0 + - @backstage/plugin-techdocs-backend@1.7.2-next.0 + - @backstage/plugin-todo-backend@0.3.3-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/plugin-app-backend@0.3.53-next.0 + - @backstage/plugin-auth-backend@0.19.2-next.0 + - @backstage/plugin-azure-devops-backend@0.4.2-next.0 + - @backstage/plugin-azure-sites-backend@0.1.15-next.0 + - @backstage/plugin-badges-backend@0.3.2-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.2-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.3.2-next.0 + - @backstage/plugin-catalog-node@1.4.6-next.0 + - @backstage/plugin-devtools-backend@0.2.2-next.0 + - @backstage/plugin-entity-feedback-backend@0.2.2-next.0 + - @backstage/plugin-events-backend@0.2.14-next.0 + - @backstage/plugin-events-node@0.2.14-next.0 + - @backstage/plugin-explore-backend@0.0.15-next.0 + - @backstage/plugin-graphql-backend@0.1.43-next.0 + - @backstage/plugin-jenkins-backend@0.2.8-next.0 + - @backstage/plugin-kafka-backend@0.3.2-next.0 + - @backstage/plugin-kubernetes-backend@0.12.2-next.0 + - @backstage/plugin-lighthouse-backend@0.3.2-next.0 + - @backstage/plugin-linguist-backend@0.5.2-next.0 + - @backstage/plugin-nomad-backend@0.1.7-next.0 + - @backstage/plugin-permission-backend@0.5.28-next.0 + - @backstage/plugin-permission-common@0.7.8 + - @backstage/plugin-permission-node@0.7.16-next.0 + - @backstage/plugin-proxy-backend@0.4.2-next.0 + - @backstage/plugin-search-backend@1.4.5-next.0 + - @backstage/plugin-search-backend-module-catalog@0.1.9-next.0 + - @backstage/plugin-search-backend-module-explore@0.1.9-next.0 + - @backstage/plugin-search-backend-module-pg@0.5.14-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.1.9-next.0 + - @backstage/plugin-search-backend-node@1.2.9-next.0 + - @backstage/plugin-search-common@1.2.6 + - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.37-next.0 + - @backstage/plugin-tech-insights-node@0.4.11-next.0 + ## 0.2.87 ### Patch Changes diff --git a/packages/backend/package.json b/packages/backend/package.json index 362f0d1201..2f2ae70e21 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -1,6 +1,6 @@ { "name": "example-backend", - "version": "0.2.87", + "version": "0.2.88-next.0", "main": "dist/index.cjs.js", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/cli-common/CHANGELOG.md b/packages/cli-common/CHANGELOG.md index bb6e2756a0..30b9670251 100644 --- a/packages/cli-common/CHANGELOG.md +++ b/packages/cli-common/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/cli-common +## 0.1.13-next.0 + +### Patch Changes + +- de42eebaaf: Bumped dev dependencies `@types/node` and `mock-fs`. + ## 0.1.12 ### Patch Changes diff --git a/packages/cli-common/package.json b/packages/cli-common/package.json index 55e6e1f792..8aed6881e2 100644 --- a/packages/cli-common/package.json +++ b/packages/cli-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/cli-common", "description": "Common functionality used by cli, backend, and create-app", - "version": "0.1.12", + "version": "0.1.13-next.0", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/cli-node/CHANGELOG.md b/packages/cli-node/CHANGELOG.md index 153bf1a5af..ab16a5d036 100644 --- a/packages/cli-node/CHANGELOG.md +++ b/packages/cli-node/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/cli-node +## 0.1.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli-common@0.1.13-next.0 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + ## 0.1.4 ### Patch Changes diff --git a/packages/cli-node/package.json b/packages/cli-node/package.json index 95c69284eb..a1062c2783 100644 --- a/packages/cli-node/package.json +++ b/packages/cli-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/cli-node", "description": "Node.js library for Backstage CLIs", - "version": "0.1.4", + "version": "0.1.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index 3e97228116..f9a93b9b44 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,31 @@ # @backstage/cli +## 0.23.0-next.0 + +### Minor Changes + +- 7077dbf131: The new backend start command that used to be enabled by setting `EXPERIMENTAL_BACKEND_START` is now the default. To revert to the old behavior, set `LEGACY_BACKEND_START` instead. + + This new command is no longer based on Webpack, but instead uses Node.js loaders to transpile on the fly. Rather than hot reloading modules the entire backend is now restarted on change, but the SQLite database state is still maintained across restarts via a parent process. + +### Patch Changes + +- 68158034e8: Fix for the new backend `start` command to make it work on Windows. +- 21cd3b1b24: Added a template for creating `node-library` packages with `yarn new`. +- de42eebaaf: Bumped dev dependencies `@types/node` and `mock-fs`. +- 3ef18f8c06: Explicitly set `exports: 'named'` for CJS builds, ensuring that they have e.g. `exports["default"] = catalogPlugin;` +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/config-loader@1.5.1-next.0 + - @backstage/cli-common@0.1.13-next.0 + - @backstage/config@1.1.0 + - @backstage/release-manifests@0.0.10 + - @backstage/catalog-model@1.4.2 + - @backstage/cli-node@0.1.5-next.0 + - @backstage/errors@1.2.2 + - @backstage/eslint-plugin@0.1.3 + - @backstage/types@1.1.1 + ## 0.22.13 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index 45d7c8468d..e49c649e8c 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.13", + "version": "0.23.0-next.0", "publishConfig": { "access": "public" }, diff --git a/packages/codemods/CHANGELOG.md b/packages/codemods/CHANGELOG.md index 9bb738e4e8..7db642945f 100644 --- a/packages/codemods/CHANGELOG.md +++ b/packages/codemods/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/codemods +## 0.1.46-next.0 + +### Patch Changes + +- de42eebaaf: Bumped dev dependencies `@types/node` and `mock-fs`. +- Updated dependencies + - @backstage/cli-common@0.1.13-next.0 + ## 0.1.45 ### Patch Changes diff --git a/packages/codemods/package.json b/packages/codemods/package.json index 484127928a..34f4b5d748 100644 --- a/packages/codemods/package.json +++ b/packages/codemods/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/codemods", "description": "A collection of codemods for Backstage projects", - "version": "0.1.45", + "version": "0.1.46-next.0", "publishConfig": { "access": "public", "main": "dist/index.cjs.js" diff --git a/packages/config-loader/CHANGELOG.md b/packages/config-loader/CHANGELOG.md index 625ee8c36e..1ee39cb9c6 100644 --- a/packages/config-loader/CHANGELOG.md +++ b/packages/config-loader/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/config-loader +## 1.5.1-next.0 + +### Patch Changes + +- 773ea341d2: The `FileConfigSource` will now retry file reading after a short delay if it reads an empty file. This is to avoid flakiness during watch mode where change events can trigger before the file content has been written. +- Updated dependencies + - @backstage/cli-common@0.1.13-next.0 + - @backstage/config@1.1.0 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + ## 1.5.0 ### Minor Changes diff --git a/packages/config-loader/package.json b/packages/config-loader/package.json index 51c7d4a599..fb17d00378 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.5.0", + "version": "1.5.1-next.0", "publishConfig": { "access": "public", "main": "dist/index.cjs.js", diff --git a/packages/core-app-api/CHANGELOG.md b/packages/core-app-api/CHANGELOG.md index bbdfd536f7..dca0c73af9 100644 --- a/packages/core-app-api/CHANGELOG.md +++ b/packages/core-app-api/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/core-app-api +## 1.10.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/config@1.1.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.5 + ## 1.10.0 ### Minor Changes diff --git a/packages/core-app-api/package.json b/packages/core-app-api/package.json index 5a687708e6..ab8fc9a155 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.10.0", + "version": "1.10.1-next.0", "publishConfig": { "access": "public" }, diff --git a/packages/core-components/CHANGELOG.md b/packages/core-components/CHANGELOG.md index db84b632af..9cf62f2694 100644 --- a/packages/core-components/CHANGELOG.md +++ b/packages/core-components/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/core-components +## 0.13.6-next.0 + +### Patch Changes + +- d19a827ef1: MissingAnnotationEmptyState component can now dynamically generate a YAML example based off the current entity being used. +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/config@1.1.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/version-bridge@1.0.5 + ## 0.13.5 ### Patch Changes diff --git a/packages/core-components/package.json b/packages/core-components/package.json index e68320ad0c..2d534609c2 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.5", + "version": "0.13.6-next.0", "publishConfig": { "access": "public", "main": "dist/index.esm.js", diff --git a/packages/core-plugin-api/CHANGELOG.md b/packages/core-plugin-api/CHANGELOG.md index 0c9728434b..d206487074 100644 --- a/packages/core-plugin-api/CHANGELOG.md +++ b/packages/core-plugin-api/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/core-plugin-api +## 1.7.0-next.0 + +### Minor Changes + +- 322bbcae24: Removed the exprimental plugin configuration API. The `__experimentalReconfigure()` from the plugin options as well as the `__experimentalConfigure()` method on plugin instances have both been removed. + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.1.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.5 + ## 1.6.0 ### Minor Changes diff --git a/packages/core-plugin-api/package.json b/packages/core-plugin-api/package.json index 34e2491ed5..64fdd00915 100644 --- a/packages/core-plugin-api/package.json +++ b/packages/core-plugin-api/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core-plugin-api", "description": "Core API used by Backstage plugins", - "version": "1.6.0", + "version": "1.7.0-next.0", "publishConfig": { "access": "public" }, diff --git a/packages/create-app/CHANGELOG.md b/packages/create-app/CHANGELOG.md index 6b7276679c..03bd32e124 100644 --- a/packages/create-app/CHANGELOG.md +++ b/packages/create-app/CHANGELOG.md @@ -1,5 +1,30 @@ # @backstage/create-app +## 0.5.6-next.0 + +### Patch Changes + +- ba6a3b59c1: Removed duplicate `apple-touch-icon` link from `packages/app/public/index.html` that linked to nonexistent icon. +- c8ec0dea4a: Create unique temp directory for each `create-app` execution. +- b665f2ce65: Change base node image from node:18-bullseye-slim to node:18-bookworm-slim due to Docker build error on bullseye. + + You can apply these change to your own `Dockerfile` by replacing `node:18-bullseye-slim` with `node:18-bookworm-slim` + +- deed089a3d: Bump `cypress` to fix the end-to-end tests +- de42eebaaf: Bumped dev dependencies `@types/node` and `mock-fs`. +- 04a3f65e15: Bump Docker base images to `node:18-bullseye-slim` to fix compatibility issues raised during image build. + + You can apply these change to your own `Dockerfile` by replacing `node:16-bullseye-slim` with `node:18-bullseye-slim` + +- 5eacd5d213: The E2E test setup based on Cypress has been replaced with one based on [Playwright](https://playwright.dev/). Migrating existing apps is not required as this is a standalone setup, only do so if you also want to switch from Cypress to Playwright. + + The scripts to run the E2E tests have been removed from `packages/app/package.json`, as they are now instead run from the root. Instead, a new script has been added to the root `package.json`, `yarn test:e2e`, which runs the E2E tests in development mode, unless `CI` is set in the environment. + + The Playwright setup uses utilities from the new `@backstage/e2e-test-utils` package to find and include all packages in the monorepo that have an `e2e-tests` folder. + +- Updated dependencies + - @backstage/cli-common@0.1.13-next.0 + ## 0.5.5 ### Patch Changes diff --git a/packages/create-app/package.json b/packages/create-app/package.json index 15db38b1c5..c46d4f43fa 100644 --- a/packages/create-app/package.json +++ b/packages/create-app/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/create-app", "description": "A CLI that helps you create your own Backstage app", - "version": "0.5.5", + "version": "0.5.6-next.0", "publishConfig": { "access": "public" }, diff --git a/packages/dev-utils/CHANGELOG.md b/packages/dev-utils/CHANGELOG.md index 434ede5d73..714ca3bd1f 100644 --- a/packages/dev-utils/CHANGELOG.md +++ b/packages/dev-utils/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/dev-utils +## 1.0.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/test-utils@1.4.4-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/integration-react@1.1.20-next.0 + - @backstage/app-defaults@1.4.4-next.0 + - @backstage/core-app-api@1.10.1-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + ## 1.0.21 ### Patch Changes diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json index 0bf405772f..fb2b086d44 100644 --- a/packages/dev-utils/package.json +++ b/packages/dev-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/dev-utils", "description": "Utilities for developing Backstage plugins.", - "version": "1.0.21", + "version": "1.0.22-next.0", "publishConfig": { "access": "public", "main": "dist/index.esm.js", diff --git a/packages/e2e-test-utils/CHANGELOG.md b/packages/e2e-test-utils/CHANGELOG.md new file mode 100644 index 0000000000..de15b39751 --- /dev/null +++ b/packages/e2e-test-utils/CHANGELOG.md @@ -0,0 +1,7 @@ +# @backstage/e2e-test-utils + +## 0.1.0-next.0 + +### Minor Changes + +- f5b41b27a9: Initial release. diff --git a/packages/e2e-test-utils/package.json b/packages/e2e-test-utils/package.json index 33e03edb3e..fcbae56796 100644 --- a/packages/e2e-test-utils/package.json +++ b/packages/e2e-test-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/e2e-test-utils", "description": "Shared end-to-end test utilities Backstage", - "version": "0.0.0", + "version": "0.1.0-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/e2e-test/CHANGELOG.md b/packages/e2e-test/CHANGELOG.md index cee3b7cc56..1fdf65a72e 100644 --- a/packages/e2e-test/CHANGELOG.md +++ b/packages/e2e-test/CHANGELOG.md @@ -1,5 +1,14 @@ # e2e-test +## 0.2.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.6-next.0 + - @backstage/cli-common@0.1.13-next.0 + - @backstage/errors@1.2.2 + ## 0.2.7 ### Patch Changes diff --git a/packages/e2e-test/package.json b/packages/e2e-test/package.json index 74f9443d51..1308c60d96 100644 --- a/packages/e2e-test/package.json +++ b/packages/e2e-test/package.json @@ -1,7 +1,7 @@ { "name": "e2e-test", "description": "E2E test for verifying Backstage packages", - "version": "0.2.7", + "version": "0.2.8-next.0", "private": true, "backstage": { "role": "cli" diff --git a/packages/frontend-app-api/CHANGELOG.md b/packages/frontend-app-api/CHANGELOG.md index f944dd1e27..a1228e084c 100644 --- a/packages/frontend-app-api/CHANGELOG.md +++ b/packages/frontend-app-api/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/frontend-app-api +## 0.2.0-next.0 + +### Minor Changes + +- 9d03dfe5e3: The `createApp` config option has been replaced by a new `configLoader` option. There is now also a `pluginLoader` option that can be used to dynamically load plugins into the app. + +### Patch Changes + +- 322bbcae24: Internal update for removal of experimental plugin configuration API. +- 66d51a4827: Prevents root extension override and duplicated plugin extensions. +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/frontend-plugin-api@0.1.1-next.0 + - @backstage/config@1.1.0 + - @backstage/core-app-api@1.10.1-next.0 + - @backstage/plugin-graphiql@0.2.55-next.0 + - @backstage/types@1.1.1 + ## 0.1.0 ### Minor Changes diff --git a/packages/frontend-app-api/package.json b/packages/frontend-app-api/package.json index 7cd4557ea1..0982cb0157 100644 --- a/packages/frontend-app-api/package.json +++ b/packages/frontend-app-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/frontend-app-api", - "version": "0.1.0", + "version": "0.2.0-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/frontend-plugin-api/CHANGELOG.md b/packages/frontend-plugin-api/CHANGELOG.md index bf0531ab43..22620aebe2 100644 --- a/packages/frontend-plugin-api/CHANGELOG.md +++ b/packages/frontend-plugin-api/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/frontend-plugin-api +## 0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/types@1.1.1 + ## 0.1.0 ### Minor Changes diff --git a/packages/frontend-plugin-api/package.json b/packages/frontend-plugin-api/package.json index 957c207617..8e71544393 100644 --- a/packages/frontend-plugin-api/package.json +++ b/packages/frontend-plugin-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/frontend-plugin-api", - "version": "0.1.0", + "version": "0.1.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/integration-react/CHANGELOG.md b/packages/integration-react/CHANGELOG.md index ff0502e498..1f6cd21668 100644 --- a/packages/integration-react/CHANGELOG.md +++ b/packages/integration-react/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/integration-react +## 1.1.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/config@1.1.0 + - @backstage/theme@0.4.2 + ## 1.1.19 ### Patch Changes diff --git a/packages/integration-react/package.json b/packages/integration-react/package.json index d08d3e0d4a..89d7cf48e9 100644 --- a/packages/integration-react/package.json +++ b/packages/integration-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/integration-react", "description": "Frontend package for managing integrations towards external systems", - "version": "1.1.19", + "version": "1.1.20-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/integration/CHANGELOG.md b/packages/integration/CHANGELOG.md index eabcfd9d4b..961e6eb869 100644 --- a/packages/integration/CHANGELOG.md +++ b/packages/integration/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/integration +## 1.7.1-next.0 + +### Patch Changes + +- 3963d0b885: Ensure that all relevant config fields are properly marked as secret +- Updated dependencies + - @backstage/config@1.1.0 + - @backstage/errors@1.2.2 + ## 1.7.0 ### Minor Changes diff --git a/packages/integration/package.json b/packages/integration/package.json index 83b137d347..ab78c07edf 100644 --- a/packages/integration/package.json +++ b/packages/integration/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/integration", "description": "Helpers for managing integrations towards external systems", - "version": "1.7.0", + "version": "1.7.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/repo-tools/CHANGELOG.md b/packages/repo-tools/CHANGELOG.md index 0b03d4808e..0864fd7347 100644 --- a/packages/repo-tools/CHANGELOG.md +++ b/packages/repo-tools/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/repo-tools +## 0.3.5-next.0 + +### Patch Changes + +- de42eebaaf: Bumped dev dependencies `@types/node` and `mock-fs`. +- Updated dependencies + - @backstage/cli-common@0.1.13-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/cli-node@0.1.5-next.0 + - @backstage/errors@1.2.2 + ## 0.3.4 ### Patch Changes diff --git a/packages/repo-tools/package.json b/packages/repo-tools/package.json index 0eb881aea8..8fc04fce71 100644 --- a/packages/repo-tools/package.json +++ b/packages/repo-tools/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/repo-tools", "description": "CLI for Backstage repo tooling ", - "version": "0.3.4", + "version": "0.3.5-next.0", "publishConfig": { "access": "public" }, diff --git a/packages/techdocs-cli-embedded-app/CHANGELOG.md b/packages/techdocs-cli-embedded-app/CHANGELOG.md index ec60ebb2fd..2e07601451 100644 --- a/packages/techdocs-cli-embedded-app/CHANGELOG.md +++ b/packages/techdocs-cli-embedded-app/CHANGELOG.md @@ -1,5 +1,24 @@ # techdocs-cli-embedded-app +## 0.2.87-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/test-utils@1.4.4-next.0 + - @backstage/cli@0.23.0-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/plugin-catalog@1.14.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/integration-react@1.1.20-next.0 + - @backstage/plugin-techdocs@1.7.1-next.0 + - @backstage/app-defaults@1.4.4-next.0 + - @backstage/config@1.1.0 + - @backstage/core-app-api@1.10.1-next.0 + - @backstage/plugin-techdocs-react@1.1.12-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + ## 0.2.86 ### Patch Changes diff --git a/packages/techdocs-cli-embedded-app/package.json b/packages/techdocs-cli-embedded-app/package.json index 9be2358760..7c5ceaf795 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.86", + "version": "0.2.87-next.0", "private": true, "backstage": { "role": "frontend" diff --git a/packages/techdocs-cli/CHANGELOG.md b/packages/techdocs-cli/CHANGELOG.md index b0d620a056..f24e216273 100644 --- a/packages/techdocs-cli/CHANGELOG.md +++ b/packages/techdocs-cli/CHANGELOG.md @@ -1,5 +1,18 @@ # @techdocs/cli +## 1.5.2-next.0 + +### Patch Changes + +- de42eebaaf: Bumped dev dependencies `@types/node` and `mock-fs`. +- 2b6e572051: Restructured tests. +- Updated dependencies + - @backstage/cli-common@0.1.13-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/plugin-techdocs-node@1.8.2-next.0 + - @backstage/config@1.1.0 + - @backstage/catalog-model@1.4.2 + ## 1.5.0 ### Minor Changes diff --git a/packages/techdocs-cli/package.json b/packages/techdocs-cli/package.json index 6883072c3b..6991e2a2c2 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.5.0", + "version": "1.5.2-next.0", "publishConfig": { "access": "public" }, diff --git a/packages/test-utils/CHANGELOG.md b/packages/test-utils/CHANGELOG.md index aad6dd3b47..f65db68aff 100644 --- a/packages/test-utils/CHANGELOG.md +++ b/packages/test-utils/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/test-utils +## 1.4.4-next.0 + +### Patch Changes + +- 322bbcae24: Removed the alpha `MockPluginProvider` export since the plugin configuration API has been removed. +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/config@1.1.0 + - @backstage/core-app-api@1.10.1-next.0 + - @backstage/plugin-permission-react@0.4.16-next.0 + - @backstage/theme@0.4.2 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.8 + ## 1.4.3 ### Patch Changes diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index 875f67ffbb..9c4c1642f6 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.4.3", + "version": "1.4.4-next.0", "publishConfig": { "access": "public" }, diff --git a/plugins/adr-backend/CHANGELOG.md b/plugins/adr-backend/CHANGELOG.md index 288acd07d6..16bf9fbc56 100644 --- a/plugins/adr-backend/CHANGELOG.md +++ b/plugins/adr-backend/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-adr-backend +## 0.4.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/plugin-adr-common@0.2.16-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/plugin-search-common@1.2.6 + ## 0.4.0 ### Minor Changes diff --git a/plugins/adr-backend/package.json b/plugins/adr-backend/package.json index 8b81223a56..ebb9367362 100644 --- a/plugins/adr-backend/package.json +++ b/plugins/adr-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-adr-backend", - "version": "0.4.0", + "version": "0.4.2-next.0", "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 73d9660fe2..961562e016 100644 --- a/plugins/adr-common/CHANGELOG.md +++ b/plugins/adr-common/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-adr-common +## 0.2.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/plugin-search-common@1.2.6 + ## 0.2.15 ### Patch Changes diff --git a/plugins/adr-common/package.json b/plugins/adr-common/package.json index 68cd5e6234..5e8e236b42 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.15", + "version": "0.2.16-next.0", "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 e433fd174b..0694cedf65 100644 --- a/plugins/adr/CHANGELOG.md +++ b/plugins/adr/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-adr +## 0.6.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/integration-react@1.1.20-next.0 + - @backstage/plugin-adr-common@0.2.16-next.0 + - @backstage/plugin-search-react@1.7.1-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + - @backstage/plugin-search-common@1.2.6 + ## 0.6.7 ### Patch Changes diff --git a/plugins/adr/package.json b/plugins/adr/package.json index 5a8eabe337..dd1e736f8a 100644 --- a/plugins/adr/package.json +++ b/plugins/adr/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-adr", - "version": "0.6.7", + "version": "0.6.8-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/airbrake-backend/CHANGELOG.md b/plugins/airbrake-backend/CHANGELOG.md index d4e68fdf50..ec047a0b83 100644 --- a/plugins/airbrake-backend/CHANGELOG.md +++ b/plugins/airbrake-backend/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-airbrake-backend +## 0.3.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + ## 0.3.0 ### Minor Changes diff --git a/plugins/airbrake-backend/package.json b/plugins/airbrake-backend/package.json index dbe7054705..3b3b21fbcb 100644 --- a/plugins/airbrake-backend/package.json +++ b/plugins/airbrake-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-airbrake-backend", - "version": "0.3.0", + "version": "0.3.2-next.0", "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 9cface3b85..9e80ddf32d 100644 --- a/plugins/airbrake/CHANGELOG.md +++ b/plugins/airbrake/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-airbrake +## 0.3.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/test-utils@1.4.4-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/dev-utils@1.0.22-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + ## 0.3.24 ### Patch Changes diff --git a/plugins/airbrake/package.json b/plugins/airbrake/package.json index f5a8f1debe..768c9c203e 100644 --- a/plugins/airbrake/package.json +++ b/plugins/airbrake/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-airbrake", - "version": "0.3.24", + "version": "0.3.25-next.0", "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 5b7971054a..04339609a4 100644 --- a/plugins/allure/CHANGELOG.md +++ b/plugins/allure/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-allure +## 0.1.41-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + ## 0.1.40 ### Patch Changes diff --git a/plugins/allure/package.json b/plugins/allure/package.json index 104dbc4313..cf33ee8696 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.40", + "version": "0.1.41-next.0", "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 6829162be7..c84c40b236 100644 --- a/plugins/analytics-module-ga/CHANGELOG.md +++ b/plugins/analytics-module-ga/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-analytics-module-ga +## 0.1.34-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/config@1.1.0 + - @backstage/theme@0.4.2 + ## 0.1.33 ### Patch Changes diff --git a/plugins/analytics-module-ga/package.json b/plugins/analytics-module-ga/package.json index 66a07699d2..006a36a490 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.33", + "version": "0.1.34-next.0", "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 34dafc1f97..8f339c47e1 100644 --- a/plugins/analytics-module-ga4/CHANGELOG.md +++ b/plugins/analytics-module-ga4/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-analytics-module-ga4 +## 0.1.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/config@1.1.0 + - @backstage/theme@0.4.2 + ## 0.1.4 ### Patch Changes diff --git a/plugins/analytics-module-ga4/package.json b/plugins/analytics-module-ga4/package.json index eb72c1ed30..fd3f6de64f 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.4", + "version": "0.1.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/analytics-module-newrelic-browser/CHANGELOG.md b/plugins/analytics-module-newrelic-browser/CHANGELOG.md index 58c4c4c575..9b62fe7596 100644 --- a/plugins/analytics-module-newrelic-browser/CHANGELOG.md +++ b/plugins/analytics-module-newrelic-browser/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-analytics-module-newrelic-browser +## 0.0.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/config@1.1.0 + ## 0.0.2 ### Patch Changes diff --git a/plugins/analytics-module-newrelic-browser/package.json b/plugins/analytics-module-newrelic-browser/package.json index 815dd3fbaf..0f2f01705a 100644 --- a/plugins/analytics-module-newrelic-browser/package.json +++ b/plugins/analytics-module-newrelic-browser/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-analytics-module-newrelic-browser", - "version": "0.0.2", + "version": "0.0.3-next.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 fd787df404..76f6ea95ed 100644 --- a/plugins/apache-airflow/CHANGELOG.md +++ b/plugins/apache-airflow/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-apache-airflow +## 0.2.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + ## 0.2.15 ### Patch Changes diff --git a/plugins/apache-airflow/package.json b/plugins/apache-airflow/package.json index a076265402..ec4bf91916 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.15", + "version": "0.2.16-next.0", "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 628cee37bb..60f00d29d5 100644 --- a/plugins/api-docs/CHANGELOG.md +++ b/plugins/api-docs/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-api-docs +## 0.9.12-next.0 + +### Patch Changes + +- 0117a6b47e: Adding `requestInterceptor` option to `api-docs` and pass it to SwaggerUI. This will enable to configure a proxy or headers to be sent to all the request made through the `Try it out` button on SwaggerUI. +- 18f1756908: added aria-label on api definition button for better a11y. +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/plugin-catalog@1.14.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + ## 0.9.11 ### Patch Changes diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json index a045d903f5..b9d7a1b6f5 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.11", + "version": "0.9.12-next.0", "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 9af673faae..3b5dd74b31 100644 --- a/plugins/apollo-explorer/CHANGELOG.md +++ b/plugins/apollo-explorer/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-apollo-explorer +## 0.1.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/theme@0.4.2 + ## 0.1.15 ### Patch Changes diff --git a/plugins/apollo-explorer/package.json b/plugins/apollo-explorer/package.json index d474094ed1..cebc6f8637 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.15", + "version": "0.1.16-next.0", "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 86eb85a42b..d3ea6acc47 100644 --- a/plugins/app-backend/CHANGELOG.md +++ b/plugins/app-backend/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-app-backend +## 0.3.53-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.5.1-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.5-next.0 + ## 0.3.51 ### Patch Changes diff --git a/plugins/app-backend/package.json b/plugins/app-backend/package.json index 561dbff245..cdbb36d23c 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.51", + "version": "0.3.53-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/app-node/CHANGELOG.md b/plugins/app-node/CHANGELOG.md index 871c31f902..48bdd793af 100644 --- a/plugins/app-node/CHANGELOG.md +++ b/plugins/app-node/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-app-node +## 0.1.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.5-next.0 + ## 0.1.3 ### Patch Changes diff --git a/plugins/app-node/package.json b/plugins/app-node/package.json index 05d49416dc..9a722915c0 100644 --- a/plugins/app-node/package.json +++ b/plugins/app-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-app-node", "description": "Node.js library for the app plugin", - "version": "0.1.3", + "version": "0.1.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-backend-module-gcp-iap-provider/CHANGELOG.md b/plugins/auth-backend-module-gcp-iap-provider/CHANGELOG.md index bfdf090263..bc44a30fd2 100644 --- a/plugins/auth-backend-module-gcp-iap-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-gcp-iap-provider/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-auth-backend-module-gcp-iap-provider +## 0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + ## 0.1.0 ### Minor Changes diff --git a/plugins/auth-backend-module-gcp-iap-provider/package.json b/plugins/auth-backend-module-gcp-iap-provider/package.json index 6764224b28..a115450273 100644 --- a/plugins/auth-backend-module-gcp-iap-provider/package.json +++ b/plugins/auth-backend-module-gcp-iap-provider/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend-module-gcp-iap-provider", "description": "A GCP IAP auth provider module for the Backstage auth backend", - "version": "0.1.0", + "version": "0.1.2-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-backend-module-github-provider/CHANGELOG.md b/plugins/auth-backend-module-github-provider/CHANGELOG.md index b7c928b62e..3055ce643c 100644 --- a/plugins/auth-backend-module-github-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-github-provider/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-auth-backend-module-github-provider +## 0.1.2-next.0 + +### Patch Changes + +- 5d32a58b5a: Fixed a bug where the GitHub authenticator did not properly persist granted OAuth scopes. +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + ## 0.1.0 ### Minor Changes diff --git a/plugins/auth-backend-module-github-provider/package.json b/plugins/auth-backend-module-github-provider/package.json index 0b86025503..b06ee136fa 100644 --- a/plugins/auth-backend-module-github-provider/package.json +++ b/plugins/auth-backend-module-github-provider/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend-module-github-provider", "description": "The github-provider backend module for the auth plugin.", - "version": "0.1.0", + "version": "0.1.2-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md b/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md index 3867635a91..4a29c21c58 100644 --- a/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-backend-module-gitlab-provider +## 0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + ## 0.1.0 ### Minor Changes diff --git a/plugins/auth-backend-module-gitlab-provider/package.json b/plugins/auth-backend-module-gitlab-provider/package.json index 49ebb0dca0..e626a02d3a 100644 --- a/plugins/auth-backend-module-gitlab-provider/package.json +++ b/plugins/auth-backend-module-gitlab-provider/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend-module-gitlab-provider", "description": "The gitlab-provider backend module for the auth plugin.", - "version": "0.1.0", + "version": "0.1.2-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-backend-module-google-provider/CHANGELOG.md b/plugins/auth-backend-module-google-provider/CHANGELOG.md index b0de32217e..bdb1d576a5 100644 --- a/plugins/auth-backend-module-google-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-google-provider/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-auth-backend-module-google-provider +## 0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + ## 0.1.0 ### Minor Changes diff --git a/plugins/auth-backend-module-google-provider/package.json b/plugins/auth-backend-module-google-provider/package.json index ac69fa91ae..e5dc87ca71 100644 --- a/plugins/auth-backend-module-google-provider/package.json +++ b/plugins/auth-backend-module-google-provider/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend-module-google-provider", "description": "A Google auth provider module for the Backstage auth backend", - "version": "0.1.0", + "version": "0.1.2-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md b/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md index 20753caa5e..f15ef3bad8 100644 --- a/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-backend-module-oauth2-provider +## 0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + ## 0.1.0 ### Minor Changes diff --git a/plugins/auth-backend-module-oauth2-provider/package.json b/plugins/auth-backend-module-oauth2-provider/package.json index 34632c4073..e18e50f44d 100644 --- a/plugins/auth-backend-module-oauth2-provider/package.json +++ b/plugins/auth-backend-module-oauth2-provider/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend-module-oauth2-provider", "description": "The oauth2-provider backend module for the auth plugin.", - "version": "0.1.0", + "version": "0.1.2-next.0", "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 fd993c5fe3..2460e7626c 100644 --- a/plugins/auth-backend/CHANGELOG.md +++ b/plugins/auth-backend/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/plugin-auth-backend +## 0.19.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-backend-module-github-provider@0.1.2-next.0 + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.1.2-next.0 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.1.2-next.0 + - @backstage/plugin-auth-backend-module-google-provider@0.1.2-next.0 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.1.2-next.0 + - @backstage/plugin-catalog-node@1.4.6-next.0 + ## 0.19.0 ### Minor Changes diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json index 98c5e0bd8a..e10568aaec 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.19.0", + "version": "0.19.2-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-node/CHANGELOG.md b/plugins/auth-node/CHANGELOG.md index ba010a155a..c3bdb44cb1 100644 --- a/plugins/auth-node/CHANGELOG.md +++ b/plugins/auth-node/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-auth-node +## 0.3.2-next.0 + +### Patch Changes + +- 6c2b0793bf: Fix for persisted scopes not being properly restored on sign-in. +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + ## 0.3.0 ### Minor Changes diff --git a/plugins/auth-node/package.json b/plugins/auth-node/package.json index 11859a899d..64b2ab4558 100644 --- a/plugins/auth-node/package.json +++ b/plugins/auth-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-node", - "version": "0.3.0", + "version": "0.3.2-next.0", "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 34fd461a3b..629bcba049 100644 --- a/plugins/azure-devops-backend/CHANGELOG.md +++ b/plugins/azure-devops-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-azure-devops-backend +## 0.4.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/plugin-azure-devops-common@0.3.1 + ## 0.4.0 ### Minor Changes diff --git a/plugins/azure-devops-backend/package.json b/plugins/azure-devops-backend/package.json index a377425b51..bc8d07b040 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.4.0", + "version": "0.4.2-next.0", "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 2712586d93..cc4f6f1e26 100644 --- a/plugins/azure-devops/CHANGELOG.md +++ b/plugins/azure-devops/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-azure-devops +## 0.3.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/plugin-azure-devops-common@0.3.1 + ## 0.3.6 ### Patch Changes diff --git a/plugins/azure-devops/package.json b/plugins/azure-devops/package.json index 740ab7d1d7..f338307ba0 100644 --- a/plugins/azure-devops/package.json +++ b/plugins/azure-devops/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-azure-devops", - "version": "0.3.6", + "version": "0.3.7-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/azure-sites-backend/CHANGELOG.md b/plugins/azure-sites-backend/CHANGELOG.md index 66c4b92c4a..06c9538119 100644 --- a/plugins/azure-sites-backend/CHANGELOG.md +++ b/plugins/azure-sites-backend/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-azure-sites-backend +## 0.1.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/plugin-azure-sites-common@0.1.1 + ## 0.1.13 ### Patch Changes diff --git a/plugins/azure-sites-backend/package.json b/plugins/azure-sites-backend/package.json index f6e08af1f2..0aa06b3e4e 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.13", + "version": "0.1.15-next.0", "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 1d9fac99a5..ef4d64fbba 100644 --- a/plugins/azure-sites/CHANGELOG.md +++ b/plugins/azure-sites/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-azure-sites +## 0.1.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + - @backstage/plugin-azure-sites-common@0.1.1 + ## 0.1.13 ### Patch Changes diff --git a/plugins/azure-sites/package.json b/plugins/azure-sites/package.json index a6147e6c02..900fb54b08 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.13", + "version": "0.1.14-next.0", "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 e778ba0eef..34c2760f7b 100644 --- a/plugins/badges-backend/CHANGELOG.md +++ b/plugins/badges-backend/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-badges-backend +## 0.3.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + ## 0.3.0 ### Minor Changes diff --git a/plugins/badges-backend/package.json b/plugins/badges-backend/package.json index 7b6f2a65b3..c4ffb180c1 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.3.0", + "version": "0.3.2-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/badges/CHANGELOG.md b/plugins/badges/CHANGELOG.md index f5bc8cc130..6b880b99eb 100644 --- a/plugins/badges/CHANGELOG.md +++ b/plugins/badges/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-badges +## 0.2.49-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + ## 0.2.48 ### Patch Changes diff --git a/plugins/badges/package.json b/plugins/badges/package.json index 8dc33ee346..d4d591aa83 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.48", + "version": "0.2.49-next.0", "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 e9fdaf4005..0606865996 100644 --- a/plugins/bazaar-backend/CHANGELOG.md +++ b/plugins/bazaar-backend/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-bazaar-backend +## 0.3.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/errors@1.2.2 + ## 0.3.0 ### Minor Changes diff --git a/plugins/bazaar-backend/package.json b/plugins/bazaar-backend/package.json index 2a2b453c6e..1cab7c95d3 100644 --- a/plugins/bazaar-backend/package.json +++ b/plugins/bazaar-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-bazaar-backend", - "version": "0.3.0", + "version": "0.3.2-next.0", "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 77f24dd5da..55fdd98b98 100644 --- a/plugins/bazaar/CHANGELOG.md +++ b/plugins/bazaar/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-bazaar +## 0.2.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/cli@0.23.0-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/plugin-catalog@1.14.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + ## 0.2.16 ### Patch Changes diff --git a/plugins/bazaar/package.json b/plugins/bazaar/package.json index 05ae2c442a..06613d6aae 100644 --- a/plugins/bazaar/package.json +++ b/plugins/bazaar/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-bazaar", - "version": "0.2.16", + "version": "0.2.17-next.0", "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 d3fb8b0eb2..439fda1b41 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.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + ## 0.2.12 ### Patch Changes diff --git a/plugins/bitbucket-cloud-common/package.json b/plugins/bitbucket-cloud-common/package.json index a0d0df7a91..5a109f3fb5 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.12", + "version": "0.2.13-next.0", "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 8564978855..afc67834b3 100644 --- a/plugins/bitrise/CHANGELOG.md +++ b/plugins/bitrise/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-bitrise +## 0.1.52-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + ## 0.1.51 ### Patch Changes diff --git a/plugins/bitrise/package.json b/plugins/bitrise/package.json index 413257109b..c94be4551d 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.51", + "version": "0.1.52-next.0", "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 70684170dd..70f1e02899 100644 --- a/plugins/catalog-backend-module-aws/CHANGELOG.md +++ b/plugins/catalog-backend-module-aws/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-catalog-backend-module-aws +## 0.2.8-next.0 + +### Patch Changes + +- 890e3b5ad4: Make sure to include the error message when ingestion fails +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/integration-aws-node@0.1.6 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-catalog-node@1.4.6-next.0 + - @backstage/plugin-kubernetes-common@0.6.6 + ## 0.2.6 ### Patch Changes diff --git a/plugins/catalog-backend-module-aws/package.json b/plugins/catalog-backend-module-aws/package.json index 3d0321e00c..c05a7c0de7 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.2.6", + "version": "0.2.8-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-azure/CHANGELOG.md b/plugins/catalog-backend-module-azure/CHANGELOG.md index 75872ba873..9864f7ca09 100644 --- a/plugins/catalog-backend-module-azure/CHANGELOG.md +++ b/plugins/catalog-backend-module-azure/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-catalog-backend-module-azure +## 0.1.24-next.0 + +### Patch Changes + +- 890e3b5ad4: Make sure to include the error message when ingestion fails +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-catalog-node@1.4.6-next.0 + ## 0.1.22 ### Patch Changes diff --git a/plugins/catalog-backend-module-azure/package.json b/plugins/catalog-backend-module-azure/package.json index 92d27e63ed..ea3ae522ee 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.22", + "version": "0.1.24-next.0", "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 a20cbb30a0..96890c9c33 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-catalog-backend-module-bitbucket-cloud +## 0.1.20-next.0 + +### Patch Changes + +- 890e3b5ad4: Make sure to include the error message when ingestion fails +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.13-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-catalog-node@1.4.6-next.0 + - @backstage/plugin-events-node@0.2.14-next.0 + ## 0.1.18 ### Patch Changes diff --git a/plugins/catalog-backend-module-bitbucket-cloud/package.json b/plugins/catalog-backend-module-bitbucket-cloud/package.json index 51f4f716b5..eb371743c4 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.18", + "version": "0.1.20-next.0", "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 766f4689a0..245c481327 100644 --- a/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-catalog-backend-module-bitbucket-server +## 0.1.18-next.0 + +### Patch Changes + +- 890e3b5ad4: Make sure to include the error message when ingestion fails +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/plugin-catalog-node@1.4.6-next.0 + ## 0.1.16 ### Patch Changes diff --git a/plugins/catalog-backend-module-bitbucket-server/package.json b/plugins/catalog-backend-module-bitbucket-server/package.json index d1819e9a3b..03547d7883 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.16", + "version": "0.1.18-next.0", "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 1782c518b5..49756558a8 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.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.13-next.0 + - @backstage/config@1.1.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.4.6-next.0 + ## 0.2.18 ### Patch Changes diff --git a/plugins/catalog-backend-module-bitbucket/package.json b/plugins/catalog-backend-module-bitbucket/package.json index 5fba12c51d..64497a2854 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.18", + "version": "0.2.20-next.0", "deprecated": true, "main": "src/index.ts", "types": "src/index.ts", diff --git a/plugins/catalog-backend-module-gcp/CHANGELOG.md b/plugins/catalog-backend-module-gcp/CHANGELOG.md index 43f6f8dc03..79bced28f5 100644 --- a/plugins/catalog-backend-module-gcp/CHANGELOG.md +++ b/plugins/catalog-backend-module-gcp/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-catalog-backend-module-gcp +## 0.1.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/plugin-catalog-node@1.4.6-next.0 + - @backstage/plugin-kubernetes-common@0.6.6 + ## 0.1.3 ### Patch Changes diff --git a/plugins/catalog-backend-module-gcp/package.json b/plugins/catalog-backend-module-gcp/package.json index 6c802154f4..66b195273c 100644 --- a/plugins/catalog-backend-module-gcp/package.json +++ b/plugins/catalog-backend-module-gcp/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-gcp", "description": "A Backstage catalog backend module that helps integrate towards GCP", - "version": "0.1.3", + "version": "0.1.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-gerrit/CHANGELOG.md b/plugins/catalog-backend-module-gerrit/CHANGELOG.md index 6e265c7fa7..486b566635 100644 --- a/plugins/catalog-backend-module-gerrit/CHANGELOG.md +++ b/plugins/catalog-backend-module-gerrit/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-catalog-backend-module-gerrit +## 0.1.21-next.0 + +### Patch Changes + +- 890e3b5ad4: Make sure to include the error message when ingestion fails +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/plugin-catalog-node@1.4.6-next.0 + ## 0.1.19 ### Patch Changes diff --git a/plugins/catalog-backend-module-gerrit/package.json b/plugins/catalog-backend-module-gerrit/package.json index 7fae34fa1f..a24644181f 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.19", + "version": "0.1.21-next.0", "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 a3def0e7f2..1851ecd90b 100644 --- a/plugins/catalog-backend-module-github/CHANGELOG.md +++ b/plugins/catalog-backend-module-github/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/plugin-catalog-backend-module-github +## 0.4.3-next.0 + +### Patch Changes + +- 890e3b5ad4: Make sure to include the error message when ingestion fails +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/plugin-catalog-backend@1.14.0-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-catalog-node@1.4.6-next.0 + - @backstage/plugin-events-node@0.2.14-next.0 + ## 0.4.0 ### Minor Changes diff --git a/plugins/catalog-backend-module-github/package.json b/plugins/catalog-backend-module-github/package.json index 4e7d4bd933..a909f1df44 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.4.0", + "version": "0.4.3-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-gitlab/CHANGELOG.md b/plugins/catalog-backend-module-gitlab/CHANGELOG.md index ff2043d1c8..c3457bbc09 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.3.2-next.0 + +### Patch Changes + +- 890e3b5ad4: Make sure to include the error message when ingestion fails +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.4.6-next.0 + ## 0.3.0 ### Minor Changes diff --git a/plugins/catalog-backend-module-gitlab/package.json b/plugins/catalog-backend-module-gitlab/package.json index b03f96aedd..5e81ed5ee6 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.3.0", + "version": "0.3.2-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md b/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md index 44ee123ceb..616890d17b 100644 --- a/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md +++ b/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-catalog-backend-module-incremental-ingestion +## 0.4.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.14.0-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/plugin-catalog-node@1.4.6-next.0 + - @backstage/plugin-events-node@0.2.14-next.0 + - @backstage/plugin-permission-common@0.7.8 + ## 0.4.6 ### Patch Changes diff --git a/plugins/catalog-backend-module-incremental-ingestion/package.json b/plugins/catalog-backend-module-incremental-ingestion/package.json index a5d1dc29eb..93e85e3db5 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.4.6", + "version": "0.4.9-next.0", "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 bf2b433fff..50c1ea8496 100644 --- a/plugins/catalog-backend-module-ldap/CHANGELOG.md +++ b/plugins/catalog-backend-module-ldap/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-backend-module-ldap +## 0.5.20-next.0 + +### Patch Changes + +- 890e3b5ad4: Make sure to include the error message when ingestion fails +- Updated dependencies + - @backstage/config@1.1.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-catalog-node@1.4.6-next.0 + ## 0.5.18 ### Patch Changes diff --git a/plugins/catalog-backend-module-ldap/package.json b/plugins/catalog-backend-module-ldap/package.json index 3e5ae84ad2..61eee3a731 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.18", + "version": "0.5.20-next.0", "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 32ca5ec085..44924c65f1 100644 --- a/plugins/catalog-backend-module-msgraph/CHANGELOG.md +++ b/plugins/catalog-backend-module-msgraph/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-backend-module-msgraph +## 0.5.12-next.0 + +### Patch Changes + +- 890e3b5ad4: Make sure to include the error message when ingestion fails +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-catalog-node@1.4.6-next.0 + ## 0.5.10 ### Patch Changes diff --git a/plugins/catalog-backend-module-msgraph/package.json b/plugins/catalog-backend-module-msgraph/package.json index 9aa539105a..1fe61cd6b2 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.10", + "version": "0.5.12-next.0", "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 0c3895b20a..3f7801bd3f 100644 --- a/plugins/catalog-backend-module-openapi/CHANGELOG.md +++ b/plugins/catalog-backend-module-openapi/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-backend-module-openapi +## 0.1.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/plugin-catalog-backend@1.14.0-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/catalog-model@1.4.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-catalog-node@1.4.6-next.0 + ## 0.1.19 ### Patch Changes diff --git a/plugins/catalog-backend-module-openapi/package.json b/plugins/catalog-backend-module-openapi/package.json index 868c75a435..cbbf6c8492 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.19", + "version": "0.1.22-next.0", "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 a2b920105a..cd71bdec72 100644 --- a/plugins/catalog-backend-module-puppetdb/CHANGELOG.md +++ b/plugins/catalog-backend-module-puppetdb/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-catalog-backend-module-puppetdb +## 0.1.10-next.0 + +### Patch Changes + +- 890e3b5ad4: Make sure to include the error message when ingestion fails +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.4.6-next.0 + ## 0.1.8 ### Patch Changes diff --git a/plugins/catalog-backend-module-puppetdb/package.json b/plugins/catalog-backend-module-puppetdb/package.json index 7eaf63b932..f54129bbcc 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.8", + "version": "0.1.10-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md b/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md index c0de55d782..bb3bbb898d 100644 --- a/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md +++ b/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-catalog-backend-module-scaffolder-entity-model +## 0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-catalog-node@1.4.6-next.0 + - @backstage/plugin-scaffolder-common@1.4.1 + ## 0.1.0 ### Minor Changes diff --git a/plugins/catalog-backend-module-scaffolder-entity-model/package.json b/plugins/catalog-backend-module-scaffolder-entity-model/package.json index f0f3ce59cf..cb8cbc16b5 100644 --- a/plugins/catalog-backend-module-scaffolder-entity-model/package.json +++ b/plugins/catalog-backend-module-scaffolder-entity-model/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-scaffolder-entity-model", "description": "Adds support for the scaffolder specific entity model (e.g. the Template kind) to the catalog backend plugin.", - "version": "0.1.0", + "version": "0.1.2-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-unprocessed/CHANGELOG.md b/plugins/catalog-backend-module-unprocessed/CHANGELOG.md index 9b8201e59f..2e15a14bfc 100644 --- a/plugins/catalog-backend-module-unprocessed/CHANGELOG.md +++ b/plugins/catalog-backend-module-unprocessed/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-catalog-backend-module-unprocessed +## 0.3.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/catalog-model@1.4.2 + ## 0.3.0 ### Minor Changes diff --git a/plugins/catalog-backend-module-unprocessed/package.json b/plugins/catalog-backend-module-unprocessed/package.json index 8cff3514ec..43e49e793d 100644 --- a/plugins/catalog-backend-module-unprocessed/package.json +++ b/plugins/catalog-backend-module-unprocessed/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-unprocessed", "description": "Backstage Catalog module to view unprocessed entities", - "version": "0.3.0", + "version": "0.3.2-next.0", "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 49ba2517f7..305b7bd1d1 100644 --- a/plugins/catalog-backend/CHANGELOG.md +++ b/plugins/catalog-backend/CHANGELOG.md @@ -1,5 +1,36 @@ # @backstage/plugin-catalog-backend +## 1.14.0-next.0 + +### Minor Changes + +- 78af9433c8: Instrumenting some missing metrics with `OpenTelemetry` + +### Patch Changes + +- 348e8c1cdb: Fixes a bug where eagerly deleted entities did not properly trigger re-stitching of entities that they had relations to. +- b97e9790f0: Internal refactors, laying the foundation for later introducing deferred stitching (see #18062). +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-openapi-utils@0.0.4 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-catalog-node@1.4.6-next.0 + - @backstage/plugin-events-node@0.2.14-next.0 + - @backstage/plugin-permission-common@0.7.8 + - @backstage/plugin-permission-node@0.7.16-next.0 + - @backstage/plugin-scaffolder-common@1.4.1 + - @backstage/plugin-search-backend-module-catalog@0.1.9-next.0 + - @backstage/plugin-search-common@1.2.6 + ## 1.13.0 ### Minor Changes diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index a1a47ed13a..7ce5d40385 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.13.0", + "version": "1.14.0-next.0", "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 c5032a1cf4..456c1b13c9 100644 --- a/plugins/catalog-graph/CHANGELOG.md +++ b/plugins/catalog-graph/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-graph +## 0.2.37-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + - @backstage/types@1.1.1 + ## 0.2.36 ### Patch Changes diff --git a/plugins/catalog-graph/package.json b/plugins/catalog-graph/package.json index 236103471f..6de95b8ec6 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.36", + "version": "0.2.37-next.0", "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 84efe07b7f..1c8cf69ead 100644 --- a/plugins/catalog-import/CHANGELOG.md +++ b/plugins/catalog-import/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-catalog-import +## 0.10.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/integration-react@1.1.20-next.0 + - @backstage/config@1.1.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/plugin-catalog-common@1.0.16 + ## 0.10.0 ### Minor Changes diff --git a/plugins/catalog-import/package.json b/plugins/catalog-import/package.json index 5d68888beb..b2661288bd 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.10.0", + "version": "0.10.1-next.0", "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 1d3b4d54da..4ab1791209 100644 --- a/plugins/catalog-node/CHANGELOG.md +++ b/plugins/catalog-node/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-catalog-node +## 1.4.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.16 + ## 1.4.4 ### Patch Changes diff --git a/plugins/catalog-node/package.json b/plugins/catalog-node/package.json index ca2de8542d..6e11ee0820 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.4.4", + "version": "1.4.6-next.0", "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 f8ddbe2a0a..8b1c4bf90e 100644 --- a/plugins/catalog-react/CHANGELOG.md +++ b/plugins/catalog-react/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-catalog-react +## 1.8.5-next.0 + +### Patch Changes + +- a402e1dfb9: Fixed an issue causing `EntityPage` to show an error for entities containing special characters +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/plugin-permission-react@0.4.16-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.5 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-permission-common@0.7.8 + ## 1.8.4 ### Patch Changes diff --git a/plugins/catalog-react/package.json b/plugins/catalog-react/package.json index 277a37e1a2..c65be47791 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.8.4", + "version": "1.8.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-unprocessed-entities/CHANGELOG.md b/plugins/catalog-unprocessed-entities/CHANGELOG.md index f797b6b5e1..8e384e95cd 100644 --- a/plugins/catalog-unprocessed-entities/CHANGELOG.md +++ b/plugins/catalog-unprocessed-entities/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-catalog-unprocessed-entities +## 0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + ## 0.1.3 ### Patch Changes diff --git a/plugins/catalog-unprocessed-entities/package.json b/plugins/catalog-unprocessed-entities/package.json index ce24df8001..0ae64d4feb 100644 --- a/plugins/catalog-unprocessed-entities/package.json +++ b/plugins/catalog-unprocessed-entities/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-unprocessed-entities", - "version": "0.1.3", + "version": "0.1.4-next.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 a26c19cfd6..a8fd34773f 100644 --- a/plugins/catalog/CHANGELOG.md +++ b/plugins/catalog/CHANGELOG.md @@ -1,5 +1,45 @@ # @backstage/plugin-catalog +## 1.14.0-next.0 + +### Minor Changes + +- 28f1ab2e1a: The catalog plugin no longer implements the experimental reconfiguration API. The create button title can now instead be configured using the new experimental internationalization API, via the `catalogTranslationRef` exported at `/alpha`. For example: + + ```ts + import { catalogTranslationRef } from '@backstage/plugin-catalog/alpha'; + + const app = createApp({ + __experimentalTranslations: { + resources: [ + createTranslationMessages({ + ref: catalogTranslationRef, + catalog_page_create_button_title: 'Create Software', + }), + ], + }, + }); + ``` + +- f3561a2935: include owner chip in catalog search result item + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/integration-react@1.1.20-next.0 + - @backstage/plugin-search-react@1.7.1-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-scaffolder-common@1.4.1 + - @backstage/plugin-search-common@1.2.6 + ## 1.13.0 ### Minor Changes diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json index dc03fb7b86..412c7d0716 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.13.0", + "version": "1.14.0-next.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 539caaef1e..e252bbe784 100644 --- a/plugins/cicd-statistics-module-gitlab/CHANGELOG.md +++ b/plugins/cicd-statistics-module-gitlab/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-cicd-statistics-module-gitlab +## 0.1.21-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/plugin-cicd-statistics@0.1.27-next.0 + - @backstage/catalog-model@1.4.2 + ## 0.1.20 ### Patch Changes diff --git a/plugins/cicd-statistics-module-gitlab/package.json b/plugins/cicd-statistics-module-gitlab/package.json index 7573ebd63e..2d2062914b 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.20", + "version": "0.1.21-next.0", "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 6a70334cb1..b195c4bab4 100644 --- a/plugins/cicd-statistics/CHANGELOG.md +++ b/plugins/cicd-statistics/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-cicd-statistics +## 0.1.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/catalog-model@1.4.2 + ## 0.1.26 ### Patch Changes diff --git a/plugins/cicd-statistics/package.json b/plugins/cicd-statistics/package.json index 9936874270..a4a6552cd2 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.26", + "version": "0.1.27-next.0", "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 71673c46eb..c29eda8985 100644 --- a/plugins/circleci/CHANGELOG.md +++ b/plugins/circleci/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-circleci +## 0.3.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + ## 0.3.24 ### Patch Changes diff --git a/plugins/circleci/package.json b/plugins/circleci/package.json index 8d897fda4f..aca3879232 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.24", + "version": "0.3.25-next.0", "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 0905269073..ced1a5b5aa 100644 --- a/plugins/cloudbuild/CHANGELOG.md +++ b/plugins/cloudbuild/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-cloudbuild +## 0.3.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + ## 0.3.24 ### Patch Changes diff --git a/plugins/cloudbuild/package.json b/plugins/cloudbuild/package.json index 74338240c6..42b706ea2d 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.24", + "version": "0.3.25-next.0", "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 749de6cd76..2728a0b8b4 100644 --- a/plugins/code-climate/CHANGELOG.md +++ b/plugins/code-climate/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-code-climate +## 0.1.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + ## 0.1.24 ### Patch Changes diff --git a/plugins/code-climate/package.json b/plugins/code-climate/package.json index 30e29490eb..5f6e89942f 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.24", + "version": "0.1.25-next.0", "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 2c4d9685e5..3f34c973ce 100644 --- a/plugins/code-coverage-backend/CHANGELOG.md +++ b/plugins/code-coverage-backend/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-code-coverage-backend +## 0.2.19-next.0 + +### Patch Changes + +- 4aa27aa200: Added option to set body size limit +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + ## 0.2.17 ### Patch Changes diff --git a/plugins/code-coverage-backend/package.json b/plugins/code-coverage-backend/package.json index f875f4d03d..fb956403b1 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.17", + "version": "0.2.19-next.0", "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 b8bf77b484..099fcbd4df 100644 --- a/plugins/code-coverage/CHANGELOG.md +++ b/plugins/code-coverage/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-code-coverage +## 0.2.18-next.0 + +### Patch Changes + +- a468544fa9: Updated layout to improve contrasts and consistency with other plugins +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/config@1.1.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + ## 0.2.17 ### Patch Changes diff --git a/plugins/code-coverage/package.json b/plugins/code-coverage/package.json index ede73b9506..05d035c45a 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.17", + "version": "0.2.18-next.0", "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 57f5fe44a9..45e23b905a 100644 --- a/plugins/codescene/CHANGELOG.md +++ b/plugins/codescene/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-codescene +## 0.1.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/config@1.1.0 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + ## 0.1.17 ### Patch Changes diff --git a/plugins/codescene/package.json b/plugins/codescene/package.json index a3a5564900..aa105dffd6 100644 --- a/plugins/codescene/package.json +++ b/plugins/codescene/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-codescene", - "version": "0.1.17", + "version": "0.1.18-next.0", "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 d6d03c1caf..877bbe23c2 100644 --- a/plugins/config-schema/CHANGELOG.md +++ b/plugins/config-schema/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-config-schema +## 0.1.46-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/config@1.1.0 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/types@1.1.1 + ## 0.1.45 ### Patch Changes diff --git a/plugins/config-schema/package.json b/plugins/config-schema/package.json index ad642a4283..1428340190 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.45", + "version": "0.1.46-next.0", "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 f74ae41fc0..5a29cfe729 100644 --- a/plugins/cost-insights/CHANGELOG.md +++ b/plugins/cost-insights/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-cost-insights +## 0.12.14-next.0 + +### Patch Changes + +- 959aa2a09f: The experimental plugin configuration has been removed. The trend line can now instead be hidden by setting `costInsights.hideTrendLine` to `true` in the configuration. +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/config@1.1.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + - @backstage/plugin-cost-insights-common@0.1.2 + ## 0.12.13 ### Patch Changes diff --git a/plugins/cost-insights/package.json b/plugins/cost-insights/package.json index 28f6ece59e..4ff0db65f4 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.13", + "version": "0.12.14-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/devtools-backend/CHANGELOG.md b/plugins/devtools-backend/CHANGELOG.md index 7d679b0aa6..4b07850d2d 100644 --- a/plugins/devtools-backend/CHANGELOG.md +++ b/plugins/devtools-backend/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-devtools-backend +## 0.2.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/config-loader@1.5.1-next.0 + - @backstage/cli-common@0.1.13-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-devtools-common@0.1.4 + - @backstage/plugin-permission-common@0.7.8 + - @backstage/plugin-permission-node@0.7.16-next.0 + ## 0.2.0 ### Minor Changes diff --git a/plugins/devtools-backend/package.json b/plugins/devtools-backend/package.json index e8a3d5b151..085b0bf37c 100644 --- a/plugins/devtools-backend/package.json +++ b/plugins/devtools-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-devtools-backend", - "version": "0.2.0", + "version": "0.2.2-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/devtools/CHANGELOG.md b/plugins/devtools/CHANGELOG.md index 2585103b45..6d8cdb219d 100644 --- a/plugins/devtools/CHANGELOG.md +++ b/plugins/devtools/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-devtools +## 0.1.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/plugin-permission-react@0.4.16-next.0 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/types@1.1.1 + - @backstage/plugin-devtools-common@0.1.4 + ## 0.1.4 ### Patch Changes diff --git a/plugins/devtools/package.json b/plugins/devtools/package.json index 44010775a8..c1b4fb2f79 100644 --- a/plugins/devtools/package.json +++ b/plugins/devtools/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-devtools", - "version": "0.1.4", + "version": "0.1.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/dynatrace/CHANGELOG.md b/plugins/dynatrace/CHANGELOG.md index 33ddc90338..a4dc207110 100644 --- a/plugins/dynatrace/CHANGELOG.md +++ b/plugins/dynatrace/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-dynatrace +## 7.0.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + ## 7.0.4 ### Patch Changes diff --git a/plugins/dynatrace/package.json b/plugins/dynatrace/package.json index 663744a454..c31e336e5c 100644 --- a/plugins/dynatrace/package.json +++ b/plugins/dynatrace/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-dynatrace", - "version": "7.0.4", + "version": "7.0.5-next.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 ac9527c416..6c2224bfcf 100644 --- a/plugins/entity-feedback-backend/CHANGELOG.md +++ b/plugins/entity-feedback-backend/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-entity-feedback-backend +## 0.2.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/plugin-entity-feedback-common@0.1.3 + ## 0.2.0 ### Minor Changes diff --git a/plugins/entity-feedback-backend/package.json b/plugins/entity-feedback-backend/package.json index 41d33eb896..6cf4117995 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.2.0", + "version": "0.2.2-next.0", "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 c470784b86..c5b67f10cf 100644 --- a/plugins/entity-feedback/CHANGELOG.md +++ b/plugins/entity-feedback/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-entity-feedback +## 0.2.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/plugin-entity-feedback-common@0.1.3 + ## 0.2.7 ### Patch Changes diff --git a/plugins/entity-feedback/package.json b/plugins/entity-feedback/package.json index b8f2333ad4..032e6732bc 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.7", + "version": "0.2.8-next.0", "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 a975bdba54..985cc6656e 100644 --- a/plugins/entity-validation/CHANGELOG.md +++ b/plugins/entity-validation/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-entity-validation +## 0.1.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/plugin-catalog-common@1.0.16 + ## 0.1.9 ### Patch Changes diff --git a/plugins/entity-validation/package.json b/plugins/entity-validation/package.json index 1a17875970..fe9ab02d0f 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.9", + "version": "0.1.10-next.0", "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 e79d836d49..f893794fdb 100644 --- a/plugins/events-backend-module-aws-sqs/CHANGELOG.md +++ b/plugins/events-backend-module-aws-sqs/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-events-backend-module-aws-sqs +## 0.2.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.2.14-next.0 + ## 0.2.6 ### Patch Changes diff --git a/plugins/events-backend-module-aws-sqs/package.json b/plugins/events-backend-module-aws-sqs/package.json index b3f0d379c2..c4fad0d1e0 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.2.6", + "version": "0.2.8-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-backend-module-azure/CHANGELOG.md b/plugins/events-backend-module-azure/CHANGELOG.md index 5289fdb465..f4d1657b0f 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.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/plugin-events-node@0.2.14-next.0 + ## 0.1.13 ### Patch Changes diff --git a/plugins/events-backend-module-azure/package.json b/plugins/events-backend-module-azure/package.json index 9cb0ff81c1..07b62130a2 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.13", + "version": "0.1.15-next.0", "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 c21e46c15b..4dbb0932e5 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.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/plugin-events-node@0.2.14-next.0 + ## 0.1.13 ### Patch Changes diff --git a/plugins/events-backend-module-bitbucket-cloud/package.json b/plugins/events-backend-module-bitbucket-cloud/package.json index d5918731d1..4011a3f496 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.13", + "version": "0.1.15-next.0", "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 d09472671a..96918cd580 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.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/plugin-events-node@0.2.14-next.0 + ## 0.1.13 ### Patch Changes diff --git a/plugins/events-backend-module-gerrit/package.json b/plugins/events-backend-module-gerrit/package.json index 9cc5f77e20..89afd8a47c 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.13", + "version": "0.1.15-next.0", "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 0fa5c1e73a..bcc3afa0ca 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.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/plugin-events-node@0.2.14-next.0 + ## 0.1.13 ### Patch Changes diff --git a/plugins/events-backend-module-github/package.json b/plugins/events-backend-module-github/package.json index ac94f83f41..a85ce50dee 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.13", + "version": "0.1.15-next.0", "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 137f700504..140b3302ac 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.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/plugin-events-node@0.2.14-next.0 + ## 0.1.13 ### Patch Changes diff --git a/plugins/events-backend-module-gitlab/package.json b/plugins/events-backend-module-gitlab/package.json index 367ff8caf2..0d8c036303 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.13", + "version": "0.1.15-next.0", "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 de26b9b864..f98f330f5b 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.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.2.14-next.0 + ## 0.1.13 ### Patch Changes diff --git a/plugins/events-backend-test-utils/package.json b/plugins/events-backend-test-utils/package.json index e749eecc28..945cbc2bf2 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.13", + "version": "0.1.15-next.0", "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 64fb6da65a..6fb1b224d2 100644 --- a/plugins/events-backend/CHANGELOG.md +++ b/plugins/events-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-events-backend +## 0.2.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/plugin-events-node@0.2.14-next.0 + ## 0.2.12 ### Patch Changes diff --git a/plugins/events-backend/package.json b/plugins/events-backend/package.json index 135971b91f..808ee2b0ec 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.12", + "version": "0.2.14-next.0", "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 e458e3e1e8..327c63a925 100644 --- a/plugins/events-node/CHANGELOG.md +++ b/plugins/events-node/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-events-node +## 0.2.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.5-next.0 + ## 0.2.12 ### Patch Changes diff --git a/plugins/events-node/package.json b/plugins/events-node/package.json index 2a27e1c200..eae224aa62 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.12", + "version": "0.2.14-next.0", "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 9518234111..5dfb9268a6 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.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/errors@1.2.2 + ## 1.0.17 ### Patch Changes diff --git a/plugins/example-todo-list-backend/package.json b/plugins/example-todo-list-backend/package.json index 27a8536c7d..2659de88bd 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.17", + "version": "1.0.18-next.0", "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 5ec4c4ea8e..9d686f4ffc 100644 --- a/plugins/example-todo-list/CHANGELOG.md +++ b/plugins/example-todo-list/CHANGELOG.md @@ -1,5 +1,14 @@ # @internal/plugin-todo-list +## 1.0.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/theme@0.4.2 + ## 1.0.17 ### Patch Changes diff --git a/plugins/example-todo-list/package.json b/plugins/example-todo-list/package.json index e61aaace42..7af06dc823 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.17", + "version": "1.0.18-next.0", "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 3baae5db72..ec8dcd45cf 100644 --- a/plugins/explore-backend/CHANGELOG.md +++ b/plugins/explore-backend/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-explore-backend +## 0.0.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/types@1.1.1 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-search-backend-module-explore@0.1.9-next.0 + - @backstage/plugin-search-common@1.2.6 + ## 0.0.13 ### Patch Changes diff --git a/plugins/explore-backend/package.json b/plugins/explore-backend/package.json index 50e179a4b9..ba5995651a 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.13", + "version": "0.0.15-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/explore-react/CHANGELOG.md b/plugins/explore-react/CHANGELOG.md index 708876c580..6d45e9a689 100644 --- a/plugins/explore-react/CHANGELOG.md +++ b/plugins/explore-react/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-explore-react +## 0.0.32-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/plugin-explore-common@0.0.2 + ## 0.0.31 ### Patch Changes diff --git a/plugins/explore-react/package.json b/plugins/explore-react/package.json index 09edad02d9..9282573a38 100644 --- a/plugins/explore-react/package.json +++ b/plugins/explore-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-explore-react", "description": "A frontend library for Backstage plugins that want to interact with the explore plugin", - "version": "0.0.31", + "version": "0.0.32-next.0", "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 5ddd9c74ad..81041c46df 100644 --- a/plugins/explore/CHANGELOG.md +++ b/plugins/explore/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-explore +## 0.4.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/plugin-explore-react@0.0.32-next.0 + - @backstage/plugin-search-react@1.7.1-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-search-common@1.2.6 + ## 0.4.10 ### Patch Changes diff --git a/plugins/explore/package.json b/plugins/explore/package.json index 1ac3ab6393..e1b210fb37 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.10", + "version": "0.4.11-next.0", "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 2e5fd2ac0f..0eab08760c 100644 --- a/plugins/firehydrant/CHANGELOG.md +++ b/plugins/firehydrant/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-firehydrant +## 0.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + ## 0.2.8 ### Patch Changes diff --git a/plugins/firehydrant/package.json b/plugins/firehydrant/package.json index f94732dd23..d6b02d8323 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.8", + "version": "0.2.9-next.0", "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 70330dd55a..35aa7423aa 100644 --- a/plugins/fossa/CHANGELOG.md +++ b/plugins/fossa/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-fossa +## 0.2.57-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + ## 0.2.56 ### Patch Changes diff --git a/plugins/fossa/package.json b/plugins/fossa/package.json index b2eba4ece9..78c39595b4 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.56", + "version": "0.2.57-next.0", "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 7eaeed8bf6..f8adef32ea 100644 --- a/plugins/gcalendar/CHANGELOG.md +++ b/plugins/gcalendar/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-gcalendar +## 0.3.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + ## 0.3.18 ### Patch Changes diff --git a/plugins/gcalendar/package.json b/plugins/gcalendar/package.json index c94f635e30..6e0166402e 100644 --- a/plugins/gcalendar/package.json +++ b/plugins/gcalendar/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-gcalendar", - "version": "0.3.18", + "version": "0.3.19-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/gcp-projects/CHANGELOG.md b/plugins/gcp-projects/CHANGELOG.md index d79cc5cbef..4f7d8546cd 100644 --- a/plugins/gcp-projects/CHANGELOG.md +++ b/plugins/gcp-projects/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-gcp-projects +## 0.3.42-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/theme@0.4.2 + ## 0.3.41 ### Patch Changes diff --git a/plugins/gcp-projects/package.json b/plugins/gcp-projects/package.json index 3f26a0eeab..7c0a6f9240 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.41", + "version": "0.3.42-next.0", "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 0d2ce7cd6b..58ee33695d 100644 --- a/plugins/git-release-manager/CHANGELOG.md +++ b/plugins/git-release-manager/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-git-release-manager +## 0.3.38-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/theme@0.4.2 + ## 0.3.37 ### Patch Changes diff --git a/plugins/git-release-manager/package.json b/plugins/git-release-manager/package.json index 1085649e35..64b0a65d87 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.37", + "version": "0.3.38-next.0", "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 e1ba36001e..1278f32354 100644 --- a/plugins/github-actions/CHANGELOG.md +++ b/plugins/github-actions/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-github-actions +## 0.6.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/integration-react@1.1.20-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + ## 0.6.5 ### Patch Changes diff --git a/plugins/github-actions/package.json b/plugins/github-actions/package.json index 26e6f45211..2d48f24492 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.6.5", + "version": "0.6.6-next.0", "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 949f6c6f7c..ba62f6bdc4 100644 --- a/plugins/github-deployments/CHANGELOG.md +++ b/plugins/github-deployments/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-github-deployments +## 0.1.56-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/integration-react@1.1.20-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + ## 0.1.55 ### Patch Changes diff --git a/plugins/github-deployments/package.json b/plugins/github-deployments/package.json index 564b20a948..71fa3a7459 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.55", + "version": "0.1.56-next.0", "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 f38c9ba630..a20c93cdeb 100644 --- a/plugins/github-issues/CHANGELOG.md +++ b/plugins/github-issues/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-github-issues +## 0.2.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + ## 0.2.13 ### Patch Changes diff --git a/plugins/github-issues/package.json b/plugins/github-issues/package.json index 8cdded424c..5b0d34effe 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.13", + "version": "0.2.14-next.0", "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 239baaaa0b..89957b1232 100644 --- a/plugins/github-pull-requests-board/CHANGELOG.md +++ b/plugins/github-pull-requests-board/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-github-pull-requests-board +## 0.1.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + ## 0.1.18 ### Patch Changes diff --git a/plugins/github-pull-requests-board/package.json b/plugins/github-pull-requests-board/package.json index 96cea6bd3a..c81a7c76d7 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.18", + "version": "0.1.19-next.0", "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 acd81f3af2..81f51796c4 100644 --- a/plugins/gitops-profiles/CHANGELOG.md +++ b/plugins/gitops-profiles/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-gitops-profiles +## 0.3.41-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/config@1.1.0 + - @backstage/theme@0.4.2 + ## 0.3.40 ### Patch Changes diff --git a/plugins/gitops-profiles/package.json b/plugins/gitops-profiles/package.json index db187a7964..56364215c5 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.40", + "version": "0.3.41-next.0", "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 c25eca242d..705ff97e0a 100644 --- a/plugins/gocd/CHANGELOG.md +++ b/plugins/gocd/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-gocd +## 0.1.31-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + ## 0.1.30 ### Patch Changes diff --git a/plugins/gocd/package.json b/plugins/gocd/package.json index 4d195ffa31..4d6f41ec62 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.30", + "version": "0.1.31-next.0", "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 c03f2e3c8f..429ca2496b 100644 --- a/plugins/graphiql/CHANGELOG.md +++ b/plugins/graphiql/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-graphiql +## 0.2.55-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/frontend-plugin-api@0.1.1-next.0 + - @backstage/theme@0.4.2 + ## 0.2.54 ### Patch Changes diff --git a/plugins/graphiql/package.json b/plugins/graphiql/package.json index 100e14e7d0..15fc394ba0 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.54", + "version": "0.2.55-next.0", "publishConfig": { "access": "public" }, diff --git a/plugins/graphql-backend/CHANGELOG.md b/plugins/graphql-backend/CHANGELOG.md index 36d30d831f..fbe80e1091 100644 --- a/plugins/graphql-backend/CHANGELOG.md +++ b/plugins/graphql-backend/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-graphql-backend +## 0.1.43-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/plugin-catalog-graphql@0.3.23 + ## 0.1.41 ### Patch Changes diff --git a/plugins/graphql-backend/package.json b/plugins/graphql-backend/package.json index d6316d3599..11fd377905 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.41", + "version": "0.1.43-next.0", "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 d521429402..ef1eb4a5c1 100644 --- a/plugins/graphql-voyager/CHANGELOG.md +++ b/plugins/graphql-voyager/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-graphql-voyager +## 0.1.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/theme@0.4.2 + ## 0.1.7 ### Patch Changes diff --git a/plugins/graphql-voyager/package.json b/plugins/graphql-voyager/package.json index 62d4e7be23..24901e8c17 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.7", + "version": "0.1.8-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/home-react/CHANGELOG.md b/plugins/home-react/CHANGELOG.md index c3dd8aefe6..197ba61e80 100644 --- a/plugins/home-react/CHANGELOG.md +++ b/plugins/home-react/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-home-react +## 0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + ## 0.1.3 ### Patch Changes diff --git a/plugins/home-react/package.json b/plugins/home-react/package.json index 9c7e3bf1db..f01adae751 100644 --- a/plugins/home-react/package.json +++ b/plugins/home-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-home-react", "description": "A Backstage plugin that contains react components helps you build a home page", - "version": "0.1.3", + "version": "0.1.4-next.0", "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 841e9ea121..f8bd2aab50 100644 --- a/plugins/home/CHANGELOG.md +++ b/plugins/home/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-home +## 0.5.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/config@1.1.0 + - @backstage/plugin-home-react@0.1.4-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + ## 0.5.8 ### Patch Changes diff --git a/plugins/home/package.json b/plugins/home/package.json index 1f4fa90148..bba62e9706 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.8", + "version": "0.5.9-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/ilert/CHANGELOG.md b/plugins/ilert/CHANGELOG.md index 45fe31099a..02d39b0594 100644 --- a/plugins/ilert/CHANGELOG.md +++ b/plugins/ilert/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-ilert +## 0.2.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + ## 0.2.13 ### Patch Changes diff --git a/plugins/ilert/package.json b/plugins/ilert/package.json index 34af0e4a5a..83cde2ff54 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.13", + "version": "0.2.14-next.0", "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 f1ded9df99..4bcb34c73c 100644 --- a/plugins/jenkins-backend/CHANGELOG.md +++ b/plugins/jenkins-backend/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-jenkins-backend +## 0.2.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/plugin-jenkins-common@0.1.19 + - @backstage/plugin-permission-common@0.7.8 + - @backstage/plugin-permission-node@0.7.16-next.0 + ## 0.2.6 ### Patch Changes diff --git a/plugins/jenkins-backend/package.json b/plugins/jenkins-backend/package.json index 542907781e..717d94733d 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.2.6", + "version": "0.2.8-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/jenkins/CHANGELOG.md b/plugins/jenkins/CHANGELOG.md index a43b0f7031..66f3d3b026 100644 --- a/plugins/jenkins/CHANGELOG.md +++ b/plugins/jenkins/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-jenkins +## 0.8.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/plugin-jenkins-common@0.1.19 + ## 0.8.6 ### Patch Changes diff --git a/plugins/jenkins/package.json b/plugins/jenkins/package.json index b936aa80b3..e3042ccb53 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.8.6", + "version": "0.8.7-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/kafka-backend/CHANGELOG.md b/plugins/kafka-backend/CHANGELOG.md index 63abf0bcc5..d5e7101f55 100644 --- a/plugins/kafka-backend/CHANGELOG.md +++ b/plugins/kafka-backend/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-kafka-backend +## 0.3.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + ## 0.3.0 ### Minor Changes diff --git a/plugins/kafka-backend/package.json b/plugins/kafka-backend/package.json index a27f72fc9a..7afdb219ab 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.3.0", + "version": "0.3.2-next.0", "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 b4acb676c3..d741d0fe2d 100644 --- a/plugins/kafka/CHANGELOG.md +++ b/plugins/kafka/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-kafka +## 0.3.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/config@1.1.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + ## 0.3.24 ### Patch Changes diff --git a/plugins/kafka/package.json b/plugins/kafka/package.json index ae8e602ce5..b48ee3322e 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.24", + "version": "0.3.25-next.0", "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 710d104033..8fc7a281db 100644 --- a/plugins/kubernetes-backend/CHANGELOG.md +++ b/plugins/kubernetes-backend/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-kubernetes-backend +## 0.12.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/integration-aws-node@0.1.6 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.4.6-next.0 + - @backstage/plugin-kubernetes-common@0.6.6 + - @backstage/plugin-permission-common@0.7.8 + - @backstage/plugin-permission-node@0.7.16-next.0 + ## 0.12.0 ### Minor Changes diff --git a/plugins/kubernetes-backend/package.json b/plugins/kubernetes-backend/package.json index dce7b512fd..54c5a35201 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.12.0", + "version": "0.12.2-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/kubernetes/CHANGELOG.md b/plugins/kubernetes/CHANGELOG.md index 3bc309c060..451825ca33 100644 --- a/plugins/kubernetes/CHANGELOG.md +++ b/plugins/kubernetes/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-kubernetes +## 0.10.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/config@1.1.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.6.6 + ## 0.10.3 ### Patch Changes diff --git a/plugins/kubernetes/package.json b/plugins/kubernetes/package.json index 80498b5b69..7f66af1296 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.10.3", + "version": "0.10.4-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/lighthouse-backend/CHANGELOG.md b/plugins/lighthouse-backend/CHANGELOG.md index 209ca47094..420f70c1d2 100644 --- a/plugins/lighthouse-backend/CHANGELOG.md +++ b/plugins/lighthouse-backend/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-lighthouse-backend +## 0.3.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.4.6-next.0 + - @backstage/plugin-lighthouse-common@0.1.3 + ## 0.3.0 ### Minor Changes diff --git a/plugins/lighthouse-backend/package.json b/plugins/lighthouse-backend/package.json index 555f3e2819..4946391d4a 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.3.0", + "version": "0.3.2-next.0", "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 56882e2a45..9690efc150 100644 --- a/plugins/lighthouse/CHANGELOG.md +++ b/plugins/lighthouse/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-lighthouse +## 0.4.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/config@1.1.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + - @backstage/plugin-lighthouse-common@0.1.3 + ## 0.4.9 ### Patch Changes diff --git a/plugins/lighthouse/package.json b/plugins/lighthouse/package.json index 3e62644212..e23b8ae742 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.9", + "version": "0.4.10-next.0", "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 10bfface1c..037bba87c2 100644 --- a/plugins/linguist-backend/CHANGELOG.md +++ b/plugins/linguist-backend/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-linguist-backend +## 0.5.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.4.6-next.0 + - @backstage/plugin-linguist-common@0.1.2 + ## 0.5.0 ### Minor Changes diff --git a/plugins/linguist-backend/package.json b/plugins/linguist-backend/package.json index d2c63c7f44..e75d9daef2 100644 --- a/plugins/linguist-backend/package.json +++ b/plugins/linguist-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-linguist-backend", - "version": "0.5.0", + "version": "0.5.2-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/linguist/CHANGELOG.md b/plugins/linguist/CHANGELOG.md index 6b0b23a4bb..eae430348d 100644 --- a/plugins/linguist/CHANGELOG.md +++ b/plugins/linguist/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-linguist +## 0.1.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/plugin-linguist-common@0.1.2 + ## 0.1.9 ### Patch Changes diff --git a/plugins/linguist/package.json b/plugins/linguist/package.json index ecae75cddf..a748670653 100644 --- a/plugins/linguist/package.json +++ b/plugins/linguist/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-linguist", - "version": "0.1.9", + "version": "0.1.10-next.0", "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 7c88ec2087..3ada5bb9d1 100644 --- a/plugins/microsoft-calendar/CHANGELOG.md +++ b/plugins/microsoft-calendar/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-microsoft-calendar +## 0.1.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + ## 0.1.7 ### Patch Changes diff --git a/plugins/microsoft-calendar/package.json b/plugins/microsoft-calendar/package.json index 8ffe31e790..5f66f361fe 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.7", + "version": "0.1.8-next.0", "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 6a6ad77acf..b7c866f7f8 100644 --- a/plugins/newrelic-dashboard/CHANGELOG.md +++ b/plugins/newrelic-dashboard/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-newrelic-dashboard +## 0.2.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + ## 0.2.17 ### Patch Changes diff --git a/plugins/newrelic-dashboard/package.json b/plugins/newrelic-dashboard/package.json index 42db37738a..d491e86ab7 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.17", + "version": "0.2.18-next.0", "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 dc69d20143..e896702b4b 100644 --- a/plugins/newrelic/CHANGELOG.md +++ b/plugins/newrelic/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-newrelic +## 0.3.41-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/theme@0.4.2 + ## 0.3.40 ### Patch Changes diff --git a/plugins/newrelic/package.json b/plugins/newrelic/package.json index 5629a10f86..1ab21391da 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.40", + "version": "0.3.41-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/nomad-backend/CHANGELOG.md b/plugins/nomad-backend/CHANGELOG.md index 9ff5e392fc..188bba8900 100644 --- a/plugins/nomad-backend/CHANGELOG.md +++ b/plugins/nomad-backend/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-nomad-backend +## 0.1.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/errors@1.2.2 + ## 0.1.5 ### Patch Changes diff --git a/plugins/nomad-backend/package.json b/plugins/nomad-backend/package.json index 24ffd9eeff..ac16ab79ec 100644 --- a/plugins/nomad-backend/package.json +++ b/plugins/nomad-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-nomad-backend", - "version": "0.1.5", + "version": "0.1.7-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/nomad/CHANGELOG.md b/plugins/nomad/CHANGELOG.md index 8f3d96519a..cf42bd5820 100644 --- a/plugins/nomad/CHANGELOG.md +++ b/plugins/nomad/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-nomad +## 0.1.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/config@1.1.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + ## 0.1.5 ### Patch Changes diff --git a/plugins/nomad/package.json b/plugins/nomad/package.json index 80971f5b6c..7e7fc1a739 100644 --- a/plugins/nomad/package.json +++ b/plugins/nomad/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-nomad", - "version": "0.1.5", + "version": "0.1.6-next.0", "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 29b46afc14..aa0f193a62 100644 --- a/plugins/octopus-deploy/CHANGELOG.md +++ b/plugins/octopus-deploy/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-octopus-deploy +## 0.2.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + ## 0.2.6 ### Patch Changes diff --git a/plugins/octopus-deploy/package.json b/plugins/octopus-deploy/package.json index 608f9d5ace..a82e7f74e1 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.6", + "version": "0.2.7-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/opencost/CHANGELOG.md b/plugins/opencost/CHANGELOG.md index ca4b9a990a..960faf29e7 100644 --- a/plugins/opencost/CHANGELOG.md +++ b/plugins/opencost/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-opencost +## 0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/theme@0.4.2 + ## 0.2.0 ### Minor Changes diff --git a/plugins/opencost/package.json b/plugins/opencost/package.json index 9db26eeb58..87b533f153 100644 --- a/plugins/opencost/package.json +++ b/plugins/opencost/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-opencost", - "version": "0.2.0", + "version": "0.2.1-next.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 fa32f33f00..71e1b94403 100644 --- a/plugins/org-react/CHANGELOG.md +++ b/plugins/org-react/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-org-react +## 0.1.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + ## 0.1.13 ### Patch Changes diff --git a/plugins/org-react/package.json b/plugins/org-react/package.json index eecdd4fa6c..a5e5a8562b 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.13", + "version": "0.1.14-next.0", "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 df02adcdfd..a2e7a2b60a 100644 --- a/plugins/org/CHANGELOG.md +++ b/plugins/org/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-org +## 0.6.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + ## 0.6.14 ### Patch Changes diff --git a/plugins/org/package.json b/plugins/org/package.json index e0483b6e64..7d931c4797 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.14", + "version": "0.6.15-next.0", "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 ad47a35b37..d9936c4f41 100644 --- a/plugins/pagerduty/CHANGELOG.md +++ b/plugins/pagerduty/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-pagerduty +## 0.6.6-next.0 + +### Patch Changes + +- b9ce306814: Minor fix to avoid usage of deprecated prop +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/plugin-home-react@0.1.4-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + ## 0.6.5 ### Patch Changes diff --git a/plugins/pagerduty/package.json b/plugins/pagerduty/package.json index 3551ab55ec..28682c2f2d 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.6.5", + "version": "0.6.6-next.0", "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 79abda94c5..448a804f23 100644 --- a/plugins/periskop-backend/CHANGELOG.md +++ b/plugins/periskop-backend/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-periskop-backend +## 0.2.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + ## 0.2.0 ### Minor Changes diff --git a/plugins/periskop-backend/package.json b/plugins/periskop-backend/package.json index 2d08441b02..ad0bcf0ad2 100644 --- a/plugins/periskop-backend/package.json +++ b/plugins/periskop-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-periskop-backend", - "version": "0.2.0", + "version": "0.2.2-next.0", "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 98dd5ff8d9..a38ca46956 100644 --- a/plugins/periskop/CHANGELOG.md +++ b/plugins/periskop/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-periskop +## 0.1.23-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + ## 0.1.22 ### Patch Changes diff --git a/plugins/periskop/package.json b/plugins/periskop/package.json index 3d4a8976a8..e2d7f6e74d 100644 --- a/plugins/periskop/package.json +++ b/plugins/periskop/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-periskop", - "version": "0.1.22", + "version": "0.1.23-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/permission-backend-module-policy-allow-all/CHANGELOG.md b/plugins/permission-backend-module-policy-allow-all/CHANGELOG.md index 64a3619daa..49b6cfd3a0 100644 --- a/plugins/permission-backend-module-policy-allow-all/CHANGELOG.md +++ b/plugins/permission-backend-module-policy-allow-all/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-permission-backend-module-allow-all-policy +## 0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/plugin-permission-common@0.7.8 + - @backstage/plugin-permission-node@0.7.16-next.0 + ## 0.1.0 ### Minor Changes diff --git a/plugins/permission-backend-module-policy-allow-all/package.json b/plugins/permission-backend-module-policy-allow-all/package.json index c2f8488369..12e60881af 100644 --- a/plugins/permission-backend-module-policy-allow-all/package.json +++ b/plugins/permission-backend-module-policy-allow-all/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-permission-backend-module-allow-all-policy", "description": "Allow all policy backend module for the permission plugin.", - "version": "0.1.0", + "version": "0.1.2-next.0", "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 b85d177879..978552f3ed 100644 --- a/plugins/permission-backend/CHANGELOG.md +++ b/plugins/permission-backend/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-permission-backend +## 0.5.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/errors@1.2.2 + - @backstage/plugin-permission-common@0.7.8 + - @backstage/plugin-permission-node@0.7.16-next.0 + ## 0.5.26 ### Patch Changes diff --git a/plugins/permission-backend/package.json b/plugins/permission-backend/package.json index 184e782782..0833e9e89b 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.26", + "version": "0.5.28-next.0", "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 5bdb0edf7b..bcdf5ce358 100644 --- a/plugins/permission-node/CHANGELOG.md +++ b/plugins/permission-node/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-permission-node +## 0.7.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/errors@1.2.2 + - @backstage/plugin-permission-common@0.7.8 + ## 0.7.14 ### Patch Changes diff --git a/plugins/permission-node/package.json b/plugins/permission-node/package.json index c90d011332..3bacf5e3ed 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.14", + "version": "0.7.16-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/permission-react/CHANGELOG.md b/plugins/permission-react/CHANGELOG.md index 45bb4dc7d9..0df727d454 100644 --- a/plugins/permission-react/CHANGELOG.md +++ b/plugins/permission-react/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-permission-react +## 0.4.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/config@1.1.0 + - @backstage/plugin-permission-common@0.7.8 + ## 0.4.15 ### Patch Changes diff --git a/plugins/permission-react/package.json b/plugins/permission-react/package.json index 267cf89f5f..7e79128739 100644 --- a/plugins/permission-react/package.json +++ b/plugins/permission-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-permission-react", - "version": "0.4.15", + "version": "0.4.16-next.0", "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 7d957d259a..0af03356ae 100644 --- a/plugins/playlist-backend/CHANGELOG.md +++ b/plugins/playlist-backend/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-playlist-backend +## 0.3.9-next.0 + +### Patch Changes + +- 9e46f5ff49: Added support to the playlist plugin for the new backend +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/plugin-permission-common@0.7.8 + - @backstage/plugin-permission-node@0.7.16-next.0 + - @backstage/plugin-playlist-common@0.1.10 + ## 0.3.7 ### Patch Changes diff --git a/plugins/playlist-backend/package.json b/plugins/playlist-backend/package.json index e3d11c2438..ac2ec35fb9 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.7", + "version": "0.3.9-next.0", "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 f3ed681214..46888d22f0 100644 --- a/plugins/playlist/CHANGELOG.md +++ b/plugins/playlist/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-playlist +## 0.1.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/plugin-permission-react@0.4.16-next.0 + - @backstage/plugin-search-react@1.7.1-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-permission-common@0.7.8 + - @backstage/plugin-playlist-common@0.1.10 + ## 0.1.16 ### Patch Changes diff --git a/plugins/playlist/package.json b/plugins/playlist/package.json index 5613a61baa..c472d8cb0c 100644 --- a/plugins/playlist/package.json +++ b/plugins/playlist/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-playlist", - "version": "0.1.16", + "version": "0.1.17-next.0", "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 81319f537b..96693d55d3 100644 --- a/plugins/proxy-backend/CHANGELOG.md +++ b/plugins/proxy-backend/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-proxy-backend +## 0.4.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + ## 0.4.0 ### Minor Changes diff --git a/plugins/proxy-backend/package.json b/plugins/proxy-backend/package.json index 2b98ba54ab..5c2d9e82c5 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.4.0", + "version": "0.4.2-next.0", "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 1fc509b29c..c1da915673 100644 --- a/plugins/puppetdb/CHANGELOG.md +++ b/plugins/puppetdb/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-puppetdb +## 0.1.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + ## 0.1.7 ### Patch Changes diff --git a/plugins/puppetdb/package.json b/plugins/puppetdb/package.json index 73c8d5d88a..cb8a9898fd 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.7", + "version": "0.1.8-next.0", "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 8f6eb0f67c..93b97226df 100644 --- a/plugins/rollbar-backend/CHANGELOG.md +++ b/plugins/rollbar-backend/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-rollbar-backend +## 0.1.50-next.0 + +### Patch Changes + +- 407f4284be: ensure rollbar token is hidden +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + ## 0.1.48 ### Patch Changes diff --git a/plugins/rollbar-backend/package.json b/plugins/rollbar-backend/package.json index 491dcd409c..596a1cf096 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.48", + "version": "0.1.50-next.0", "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 77e2631e93..6bd10a118f 100644 --- a/plugins/rollbar/CHANGELOG.md +++ b/plugins/rollbar/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-rollbar +## 0.4.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + ## 0.4.24 ### Patch Changes diff --git a/plugins/rollbar/package.json b/plugins/rollbar/package.json index 262b51abc0..fb3171d2dc 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.24", + "version": "0.4.25-next.0", "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 7ccbb5e286..a2d833056a 100644 --- a/plugins/scaffolder-backend-module-confluence-to-markdown/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-confluence-to-markdown/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-scaffolder-backend-module-confluence-to-markdown +## 0.2.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/plugin-scaffolder-node@0.2.5-next.0 + - @backstage/config@1.1.0 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + ## 0.2.4 ### 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 b1ce79bf1d..9160a70062 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.2.4", + "version": "0.2.6-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md b/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md index 5662119c27..ee0b07ee8b 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-scaffolder-backend-module-cookiecutter +## 0.2.29-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/plugin-scaffolder-node@0.2.5-next.0 + - @backstage/config@1.1.0 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + ## 0.2.27 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-cookiecutter/package.json b/plugins/scaffolder-backend-module-cookiecutter/package.json index 152b103919..9ef5c6f3ec 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.27", + "version": "0.2.29-next.0", "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 44c9337b17..fbb987bb11 100644 --- a/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-scaffolder-backend-module-gitlab +## 0.2.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/plugin-scaffolder-node@0.2.5-next.0 + - @backstage/config@1.1.0 + - @backstage/errors@1.2.2 + ## 0.2.6 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-gitlab/package.json b/plugins/scaffolder-backend-module-gitlab/package.json index e34ee93523..71ee372afc 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.2.6", + "version": "0.2.8-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend-module-rails/CHANGELOG.md b/plugins/scaffolder-backend-module-rails/CHANGELOG.md index eed053be6f..bc5965d9be 100644 --- a/plugins/scaffolder-backend-module-rails/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-rails/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-scaffolder-backend-module-rails +## 0.4.22-next.0 + +### Patch Changes + +- de42eebaaf: Bumped dev dependencies `@types/node` and `mock-fs`. +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/plugin-scaffolder-node@0.2.5-next.0 + - @backstage/config@1.1.0 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + ## 0.4.20 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-rails/package.json b/plugins/scaffolder-backend-module-rails/package.json index f53072ebc3..586bc2e7dc 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.20", + "version": "0.4.22-next.0", "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 ad10b1467c..f13f300877 100644 --- a/plugins/scaffolder-backend-module-sentry/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-sentry/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-scaffolder-backend-module-sentry +## 0.1.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.2.5-next.0 + - @backstage/config@1.1.0 + - @backstage/errors@1.2.2 + ## 0.1.11 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-sentry/package.json b/plugins/scaffolder-backend-module-sentry/package.json index d735b34666..74e0d7b397 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.11", + "version": "0.1.13-next.0", "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 d2df8786c0..14d2ef1c08 100644 --- a/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-scaffolder-backend-module-yeoman +## 0.2.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.2.5-next.0 + - @backstage/config@1.1.0 + - @backstage/types@1.1.1 + ## 0.2.24 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-yeoman/package.json b/plugins/scaffolder-backend-module-yeoman/package.json index 2eec398969..e4e6b2941c 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.24", + "version": "0.2.26-next.0", "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 9dd4c120b5..a512a87555 100644 --- a/plugins/scaffolder-backend/CHANGELOG.md +++ b/plugins/scaffolder-backend/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-scaffolder-backend +## 1.17.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/plugin-catalog-backend@1.14.0-next.0 + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/plugin-scaffolder-node@0.2.5-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.2-next.0 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-catalog-node@1.4.6-next.0 + - @backstage/plugin-permission-common@0.7.8 + - @backstage/plugin-permission-node@0.7.16-next.0 + - @backstage/plugin-scaffolder-common@1.4.1 + ## 1.17.0 ### Minor Changes diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index 99f6256069..550ad90b47 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.17.0", + "version": "1.17.3-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-node/CHANGELOG.md b/plugins/scaffolder-node/CHANGELOG.md index 6d21eef023..e4f43dd69e 100644 --- a/plugins/scaffolder-node/CHANGELOG.md +++ b/plugins/scaffolder-node/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-scaffolder-node +## 0.2.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.4.1 + ## 0.2.3 ### Patch Changes diff --git a/plugins/scaffolder-node/package.json b/plugins/scaffolder-node/package.json index 694e440ef9..b6d2bde6e9 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.2.3", + "version": "0.2.5-next.0", "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 3b41c76469..dcb87e1497 100644 --- a/plugins/scaffolder-react/CHANGELOG.md +++ b/plugins/scaffolder-react/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-scaffolder-react +## 1.5.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.5 + - @backstage/plugin-scaffolder-common@1.4.1 + ## 1.5.5 ### Patch Changes diff --git a/plugins/scaffolder-react/package.json b/plugins/scaffolder-react/package.json index e6859ad369..eb8d886b9a 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.5.5", + "version": "1.5.6-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder/CHANGELOG.md b/plugins/scaffolder/CHANGELOG.md index 940331aa80..4cb5125f4f 100644 --- a/plugins/scaffolder/CHANGELOG.md +++ b/plugins/scaffolder/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-scaffolder +## 1.15.1-next.0 + +### Patch Changes + +- b337d78c3b: fixed issue related template editor fails with multiple templates per file. +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/integration-react@1.1.20-next.0 + - @backstage/plugin-scaffolder-react@1.5.6-next.0 + - @backstage/config@1.1.0 + - @backstage/plugin-permission-react@0.4.16-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-scaffolder-common@1.4.1 + ## 1.15.0 ### Minor Changes diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index 2e28f70cff..086ef3cea1 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.15.0", + "version": "1.15.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-backend-module-catalog/CHANGELOG.md b/plugins/search-backend-module-catalog/CHANGELOG.md index ed17ffbf63..46f3b4c9de 100644 --- a/plugins/search-backend-module-catalog/CHANGELOG.md +++ b/plugins/search-backend-module-catalog/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-search-backend-module-catalog +## 0.1.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-catalog-node@1.4.6-next.0 + - @backstage/plugin-permission-common@0.7.8 + - @backstage/plugin-search-backend-node@1.2.9-next.0 + - @backstage/plugin-search-common@1.2.6 + ## 0.1.7 ### Patch Changes diff --git a/plugins/search-backend-module-catalog/package.json b/plugins/search-backend-module-catalog/package.json index 1fb18a303b..11f64cf817 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.7", + "version": "0.1.9-next.0", "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 6b0bb7ce1a..f56b1f28da 100644 --- a/plugins/search-backend-module-elasticsearch/CHANGELOG.md +++ b/plugins/search-backend-module-elasticsearch/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-search-backend-module-elasticsearch +## 1.3.8-next.0 + +### Patch Changes + +- 3963d0b885: Ensure that all relevant config fields are properly marked as secret +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/integration-aws-node@0.1.6 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/plugin-search-backend-node@1.2.9-next.0 + - @backstage/plugin-search-common@1.2.6 + ## 1.3.6 ### Patch Changes diff --git a/plugins/search-backend-module-elasticsearch/package.json b/plugins/search-backend-module-elasticsearch/package.json index f1c9f39a17..2750e1d2dc 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.3.6", + "version": "1.3.8-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-backend-module-explore/CHANGELOG.md b/plugins/search-backend-module-explore/CHANGELOG.md index dfcfa262de..5260222ed3 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.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-search-backend-node@1.2.9-next.0 + - @backstage/plugin-search-common@1.2.6 + ## 0.1.7 ### Patch Changes diff --git a/plugins/search-backend-module-explore/package.json b/plugins/search-backend-module-explore/package.json index 630020a93d..a4a1dcf881 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.7", + "version": "0.1.9-next.0", "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 e119c76e26..b49fb7aad9 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.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/plugin-search-backend-node@1.2.9-next.0 + - @backstage/plugin-search-common@1.2.6 + ## 0.5.12 ### Patch Changes diff --git a/plugins/search-backend-module-pg/package.json b/plugins/search-backend-module-pg/package.json index a411464d52..10536678d5 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.12", + "version": "0.5.14-next.0", "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 6a0fd46b02..666fe0a7c3 100644 --- a/plugins/search-backend-module-techdocs/CHANGELOG.md +++ b/plugins/search-backend-module-techdocs/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-search-backend-module-techdocs +## 0.1.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/plugin-techdocs-node@1.8.2-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-catalog-node@1.4.6-next.0 + - @backstage/plugin-permission-common@0.7.8 + - @backstage/plugin-search-backend-node@1.2.9-next.0 + - @backstage/plugin-search-common@1.2.6 + ## 0.1.7 ### Patch Changes diff --git a/plugins/search-backend-module-techdocs/package.json b/plugins/search-backend-module-techdocs/package.json index fda3d1cd8f..075403d512 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.7", + "version": "0.1.9-next.0", "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 a6374f7701..bfdf91c150 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.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/errors@1.2.2 + - @backstage/plugin-permission-common@0.7.8 + - @backstage/plugin-search-common@1.2.6 + ## 1.2.7 ### Patch Changes diff --git a/plugins/search-backend-node/package.json b/plugins/search-backend-node/package.json index cc688e7bb6..3e87e29ce9 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.7", + "version": "1.2.9-next.0", "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 b7c6873af2..af05809517 100644 --- a/plugins/search-backend/CHANGELOG.md +++ b/plugins/search-backend/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-search-backend +## 1.4.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-openapi-utils@0.0.4 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.8 + - @backstage/plugin-permission-node@0.7.16-next.0 + - @backstage/plugin-search-backend-node@1.2.9-next.0 + - @backstage/plugin-search-common@1.2.6 + ## 1.4.3 ### Patch Changes diff --git a/plugins/search-backend/package.json b/plugins/search-backend/package.json index fc02e552cd..c71356dda3 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.4.3", + "version": "1.4.5-next.0", "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 f01b5b0a54..7904129b3e 100644 --- a/plugins/search-react/CHANGELOG.md +++ b/plugins/search-react/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-search-react +## 1.7.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/theme@0.4.2 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.5 + - @backstage/plugin-search-common@1.2.6 + ## 1.7.0 ### Minor Changes diff --git a/plugins/search-react/package.json b/plugins/search-react/package.json index 9ed330c37b..4454d44574 100644 --- a/plugins/search-react/package.json +++ b/plugins/search-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-react", - "version": "1.7.0", + "version": "1.7.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search/CHANGELOG.md b/plugins/search/CHANGELOG.md index 24ea0920c7..0a5b57b7a2 100644 --- a/plugins/search/CHANGELOG.md +++ b/plugins/search/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-search +## 1.4.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/config@1.1.0 + - @backstage/plugin-search-react@1.7.1-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.5 + - @backstage/plugin-search-common@1.2.6 + ## 1.4.0 ### Minor Changes diff --git a/plugins/search/package.json b/plugins/search/package.json index d31a9e0c1f..77c3bd4727 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.4.0", + "version": "1.4.1-next.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 dcb5684f9a..5f28cbf0fd 100644 --- a/plugins/sentry/CHANGELOG.md +++ b/plugins/sentry/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-sentry +## 0.5.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + ## 0.5.9 ### Patch Changes diff --git a/plugins/sentry/package.json b/plugins/sentry/package.json index be9230572d..242e26ff51 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.9", + "version": "0.5.10-next.0", "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 c8774a9fcb..1e168daa77 100644 --- a/plugins/shortcuts/CHANGELOG.md +++ b/plugins/shortcuts/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-shortcuts +## 0.3.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/theme@0.4.2 + - @backstage/types@1.1.1 + ## 0.3.14 ### Patch Changes diff --git a/plugins/shortcuts/package.json b/plugins/shortcuts/package.json index a344e111c6..994dabbd1d 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.14", + "version": "0.3.15-next.0", "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 f7353f9985..a7b8b4e171 100644 --- a/plugins/sonarqube-backend/CHANGELOG.md +++ b/plugins/sonarqube-backend/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-sonarqube-backend +## 0.2.7-next.0 + +### Patch Changes + +- a5d592d0ad: Added support for the [new backend system](https://backstage.io/docs/backend-system/) +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/errors@1.2.2 + ## 0.2.5 ### Patch Changes diff --git a/plugins/sonarqube-backend/package.json b/plugins/sonarqube-backend/package.json index ccfbc4e92a..89c96bfcf4 100644 --- a/plugins/sonarqube-backend/package.json +++ b/plugins/sonarqube-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-sonarqube-backend", - "version": "0.2.5", + "version": "0.2.7-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/sonarqube-react/CHANGELOG.md b/plugins/sonarqube-react/CHANGELOG.md index e8fdd45a40..5fea1d2e9e 100644 --- a/plugins/sonarqube-react/CHANGELOG.md +++ b/plugins/sonarqube-react/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-sonarqube-react +## 0.1.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/catalog-model@1.4.2 + ## 0.1.8 ### Patch Changes diff --git a/plugins/sonarqube-react/package.json b/plugins/sonarqube-react/package.json index 7ffb55ad69..6e1adb42f9 100644 --- a/plugins/sonarqube-react/package.json +++ b/plugins/sonarqube-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-sonarqube-react", - "version": "0.1.8", + "version": "0.1.9-next.0", "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 178058ef03..0fa5143c1a 100644 --- a/plugins/sonarqube/CHANGELOG.md +++ b/plugins/sonarqube/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-sonarqube +## 0.7.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + - @backstage/plugin-sonarqube-react@0.1.9-next.0 + ## 0.7.5 ### Patch Changes diff --git a/plugins/sonarqube/package.json b/plugins/sonarqube/package.json index 238423fc98..780b81468a 100644 --- a/plugins/sonarqube/package.json +++ b/plugins/sonarqube/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-sonarqube", "description": "", - "version": "0.7.5", + "version": "0.7.6-next.0", "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 3360ebdcae..76bd4b9ddb 100644 --- a/plugins/splunk-on-call/CHANGELOG.md +++ b/plugins/splunk-on-call/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-splunk-on-call +## 0.4.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/theme@0.4.2 + ## 0.4.13 ### Patch Changes diff --git a/plugins/splunk-on-call/package.json b/plugins/splunk-on-call/package.json index d86d555fe1..ab6155e96c 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.13", + "version": "0.4.14-next.0", "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 f5922da46c..6eb8d27731 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.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/plugin-search-common@1.2.6 + ## 0.2.7 ### Patch Changes diff --git a/plugins/stack-overflow-backend/package.json b/plugins/stack-overflow-backend/package.json index 2825bfc310..f090c8d25f 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.7", + "version": "0.2.9-next.0", "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 857aa92607..12cf74570e 100644 --- a/plugins/stack-overflow/CHANGELOG.md +++ b/plugins/stack-overflow/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-stack-overflow +## 0.1.21-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/config@1.1.0 + - @backstage/plugin-home-react@0.1.4-next.0 + - @backstage/plugin-search-react@1.7.1-next.0 + - @backstage/theme@0.4.2 + - @backstage/plugin-search-common@1.2.6 + ## 0.1.20 ### Patch Changes diff --git a/plugins/stack-overflow/package.json b/plugins/stack-overflow/package.json index 2e211987c4..7be47012e8 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.20", + "version": "0.1.21-next.0", "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 fcb1dfed42..c8056438d7 100644 --- a/plugins/stackstorm/CHANGELOG.md +++ b/plugins/stackstorm/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-stackstorm +## 0.1.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + ## 0.1.6 ### Patch Changes diff --git a/plugins/stackstorm/package.json b/plugins/stackstorm/package.json index df9a9f1d41..a65e8692e2 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.6", + "version": "0.1.7-next.0", "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 78a66da5a4..a884f1dfc7 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.37-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/errors@1.2.2 + - @backstage/plugin-tech-insights-common@0.2.12 + - @backstage/plugin-tech-insights-node@0.4.11-next.0 + ## 0.1.35 ### Patch Changes diff --git a/plugins/tech-insights-backend-module-jsonfc/package.json b/plugins/tech-insights-backend-module-jsonfc/package.json index 65e94067e2..8823de7697 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.35", + "version": "0.1.37-next.0", "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 368490c8bb..fe3f4ce37c 100644 --- a/plugins/tech-insights-backend/CHANGELOG.md +++ b/plugins/tech-insights-backend/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-tech-insights-backend +## 0.5.19-next.0 + +### Patch Changes + +- cc7dddfa7f: Increase the maximum allowed length of an entity filter for tech insights fact schemas. +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + - @backstage/plugin-tech-insights-node@0.4.11-next.0 + ## 0.5.17 ### Patch Changes diff --git a/plugins/tech-insights-backend/package.json b/plugins/tech-insights-backend/package.json index 2aa1a4793f..2b5a427eef 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.17", + "version": "0.5.19-next.0", "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 a2669c4e4a..2a29e65bf2 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.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + ## 0.4.9 ### Patch Changes diff --git a/plugins/tech-insights-node/package.json b/plugins/tech-insights-node/package.json index 0dae5947f1..80befca1d1 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.9", + "version": "0.4.11-next.0", "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 56648e0cda..83bd2f6d1c 100644 --- a/plugins/tech-insights/CHANGELOG.md +++ b/plugins/tech-insights/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-tech-insights +## 0.3.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + ## 0.3.16 ### Patch Changes diff --git a/plugins/tech-insights/package.json b/plugins/tech-insights/package.json index d3ae234abc..a0f74ff425 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.16", + "version": "0.3.17-next.0", "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 385b536004..48369b1e49 100644 --- a/plugins/tech-radar/CHANGELOG.md +++ b/plugins/tech-radar/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-tech-radar +## 0.6.9-next.0 + +### Patch Changes + +- c09d2fa1d6: Added experimental support for the declarative integration. +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/frontend-plugin-api@0.1.1-next.0 + - @backstage/theme@0.4.2 + ## 0.6.8 ### Patch Changes diff --git a/plugins/tech-radar/package.json b/plugins/tech-radar/package.json index 221aa6b0d2..7505fa0813 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.8", + "version": "0.6.9-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/techdocs-addons-test-utils/CHANGELOG.md b/plugins/techdocs-addons-test-utils/CHANGELOG.md index 7c1c5eb0e3..812543f3c8 100644 --- a/plugins/techdocs-addons-test-utils/CHANGELOG.md +++ b/plugins/techdocs-addons-test-utils/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-techdocs-addons-test-utils +## 1.0.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/test-utils@1.4.4-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/plugin-catalog@1.14.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/integration-react@1.1.20-next.0 + - @backstage/plugin-techdocs@1.7.1-next.0 + - @backstage/core-app-api@1.10.1-next.0 + - @backstage/plugin-search-react@1.7.1-next.0 + - @backstage/plugin-techdocs-react@1.1.12-next.0 + - @backstage/theme@0.4.2 + ## 1.0.21 ### Patch Changes diff --git a/plugins/techdocs-addons-test-utils/package.json b/plugins/techdocs-addons-test-utils/package.json index af016f8c32..0a88a3d99f 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.21", + "version": "1.0.22-next.0", "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 55b6aefe3f..7566b7baff 100644 --- a/plugins/techdocs-backend/CHANGELOG.md +++ b/plugins/techdocs-backend/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-techdocs-backend +## 1.7.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/plugin-techdocs-node@1.8.2-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/plugin-catalog-common@1.0.16 + - @backstage/plugin-permission-common@0.7.8 + - @backstage/plugin-search-backend-module-techdocs@0.1.9-next.0 + - @backstage/plugin-search-common@1.2.6 + ## 1.7.0 ### Minor Changes diff --git a/plugins/techdocs-backend/package.json b/plugins/techdocs-backend/package.json index f4e13111dc..935990c305 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.7.0", + "version": "1.7.2-next.0", "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 68bf1fce2e..3f79ff32b8 100644 --- a/plugins/techdocs-module-addons-contrib/CHANGELOG.md +++ b/plugins/techdocs-module-addons-contrib/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-techdocs-module-addons-contrib +## 1.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/integration-react@1.1.20-next.0 + - @backstage/plugin-techdocs-react@1.1.12-next.0 + - @backstage/theme@0.4.2 + ## 1.1.0 ### Minor Changes diff --git a/plugins/techdocs-module-addons-contrib/package.json b/plugins/techdocs-module-addons-contrib/package.json index 6ffb5c4afa..933f18eb48 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.1.0", + "version": "1.1.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/techdocs-node/CHANGELOG.md b/plugins/techdocs-node/CHANGELOG.md index 06d0d88fae..dca68479be 100644 --- a/plugins/techdocs-node/CHANGELOG.md +++ b/plugins/techdocs-node/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-techdocs-node +## 1.8.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/integration-aws-node@0.1.6 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/plugin-search-common@1.2.6 + ## 1.8.0 ### Minor Changes diff --git a/plugins/techdocs-node/package.json b/plugins/techdocs-node/package.json index 28de8a94fd..35feb3b0b4 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.8.0", + "version": "1.8.2-next.0", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/plugins/techdocs-react/CHANGELOG.md b/plugins/techdocs-react/CHANGELOG.md index 9e14cdbf36..f14e5b5a60 100644 --- a/plugins/techdocs-react/CHANGELOG.md +++ b/plugins/techdocs-react/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-techdocs-react +## 1.1.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/config@1.1.0 + - @backstage/catalog-model@1.4.2 + - @backstage/version-bridge@1.0.5 + ## 1.1.11 ### Patch Changes diff --git a/plugins/techdocs-react/package.json b/plugins/techdocs-react/package.json index c07283c0b4..79ef7241f0 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.11", + "version": "1.1.12-next.0", "publishConfig": { "access": "public", "main": "dist/index.esm.js", diff --git a/plugins/techdocs/CHANGELOG.md b/plugins/techdocs/CHANGELOG.md index e834585259..e2256c8f15 100644 --- a/plugins/techdocs/CHANGELOG.md +++ b/plugins/techdocs/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-techdocs +## 1.7.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/integration-react@1.1.20-next.0 + - @backstage/config@1.1.0 + - @backstage/plugin-search-react@1.7.1-next.0 + - @backstage/plugin-techdocs-react@1.1.12-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/plugin-search-common@1.2.6 + ## 1.7.0 ### Minor Changes diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index a1f26694f8..7a34577f01 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.7.0", + "version": "1.7.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/todo-backend/CHANGELOG.md b/plugins/todo-backend/CHANGELOG.md index e468aa66e6..e7afb9ecd0 100644 --- a/plugins/todo-backend/CHANGELOG.md +++ b/plugins/todo-backend/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-todo-backend +## 0.3.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-openapi-utils@0.0.4 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/catalog-client@1.4.4 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/plugin-catalog-node@1.4.6-next.0 + ## 0.3.1 ### Minor Changes diff --git a/plugins/todo-backend/package.json b/plugins/todo-backend/package.json index 1f9c74e11c..1d4f396de1 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.3.1", + "version": "0.3.3-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/todo/CHANGELOG.md b/plugins/todo/CHANGELOG.md index f4ea8e5a23..7e9e8c6933 100644 --- a/plugins/todo/CHANGELOG.md +++ b/plugins/todo/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-todo +## 0.2.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + ## 0.2.27 ### Patch Changes diff --git a/plugins/todo/package.json b/plugins/todo/package.json index 21a9dbaf6a..fa1d1d9e62 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.27", + "version": "0.2.28-next.0", "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 e3bcd23555..9af11fffbf 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.2.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + ## 0.2.1 ### Minor Changes diff --git a/plugins/user-settings-backend/package.json b/plugins/user-settings-backend/package.json index 6d0b85b06c..0feaba734e 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.2.1", + "version": "0.2.3-next.0", "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 011e0e2511..9e81589e7d 100644 --- a/plugins/user-settings/CHANGELOG.md +++ b/plugins/user-settings/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-user-settings +## 0.7.11-next.0 + +### Patch Changes + +- d1b637d005: Fixed a bug where the theme icons would not be colored according to their active state. +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/core-app-api@1.10.1-next.0 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/types@1.1.1 + ## 0.7.10 ### Patch Changes diff --git a/plugins/user-settings/package.json b/plugins/user-settings/package.json index 01e158dc2c..d2c9f440e6 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.10", + "version": "0.7.11-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/vault-backend/CHANGELOG.md b/plugins/vault-backend/CHANGELOG.md index a15ae01ac6..fcb259e047 100644 --- a/plugins/vault-backend/CHANGELOG.md +++ b/plugins/vault-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-vault-backend +## 0.3.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.0 + - @backstage/config@1.1.0 + - @backstage/backend-tasks@0.5.10-next.0 + - @backstage/errors@1.2.2 + ## 0.3.8 ### Patch Changes diff --git a/plugins/vault-backend/package.json b/plugins/vault-backend/package.json index 034e8474aa..f8de4e2845 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.8", + "version": "0.3.10-next.0", "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 79f7427d28..940345da8d 100644 --- a/plugins/vault/CHANGELOG.md +++ b/plugins/vault/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-vault +## 0.1.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + ## 0.1.19 ### Patch Changes diff --git a/plugins/vault/package.json b/plugins/vault/package.json index dcc7a03d62..d571efe444 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.19", + "version": "0.1.20-next.0", "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 61f0561fbf..c296cc3e0b 100644 --- a/plugins/xcmetrics/CHANGELOG.md +++ b/plugins/xcmetrics/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-xcmetrics +## 0.2.44-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + ## 0.2.43 ### Patch Changes diff --git a/plugins/xcmetrics/package.json b/plugins/xcmetrics/package.json index ee16b186c1..b63915c1f0 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.43", + "version": "0.2.44-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/yarn.lock b/yarn.lock index 3badc585b4..c1887a4ea0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3661,7 +3661,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/catalog-client@workspace:^, @backstage/catalog-client@workspace:packages/catalog-client": +"@backstage/catalog-client@^1.4.4, @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: @@ -3673,7 +3673,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/catalog-model@^1.1.5, @backstage/catalog-model@^1.4.1, @backstage/catalog-model@workspace:^, @backstage/catalog-model@workspace:packages/catalog-model": +"@backstage/catalog-model@^1.1.5, @backstage/catalog-model@^1.4.1, @backstage/catalog-model@^1.4.2, @backstage/catalog-model@workspace:^, @backstage/catalog-model@workspace:packages/catalog-model": version: 0.0.0-use.local resolution: "@backstage/catalog-model@workspace:packages/catalog-model" dependencies: @@ -3921,7 +3921,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/config@^1.0.6, @backstage/config@^1.0.7, @backstage/config@workspace:^, @backstage/config@workspace:packages/config": +"@backstage/config@^1.0.6, @backstage/config@^1.0.7, @backstage/config@^1.1.0, @backstage/config@workspace:^, @backstage/config@workspace:packages/config": version: 0.0.0-use.local resolution: "@backstage/config@workspace:packages/config" dependencies: @@ -3969,7 +3969,111 @@ __metadata: languageName: unknown linkType: soft -"@backstage/core-components@^0.13.4, @backstage/core-components@workspace:^, @backstage/core-components@workspace:packages/core-components": +"@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.4, @backstage/core-components@npm:^0.13.5": + version: 0.13.5 + resolution: "@backstage/core-components@npm:0.13.5" + dependencies: + "@backstage/config": ^1.1.0 + "@backstage/core-plugin-api": ^1.6.0 + "@backstage/errors": ^1.2.2 + "@backstage/theme": ^0.4.2 + "@backstage/version-bridge": ^1.0.5 + "@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.5.1 + react-helmet: 6.1.0 + react-hook-form: ^7.12.2 + react-idle-timer: 5.6.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: f1c9290fd1358561c9a1098200cdf1d2dc16117aebf4010759f122b0a638acb50a89faa24988ad4a854ace59a74606329550c59fc98ab6281feb4b4f5bfe52c0 + languageName: node + linkType: hard + +"@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: @@ -4046,57 +4150,27 @@ __metadata: languageName: unknown linkType: soft -"@backstage/core-components@npm:^0.12.3": - version: 0.12.5 - resolution: "@backstage/core-components@npm:0.12.5" +"@backstage/core-plugin-api@npm:^1.3.0, @backstage/core-plugin-api@npm:^1.5.0, @backstage/core-plugin-api@npm:^1.5.3, @backstage/core-plugin-api@npm:^1.6.0": + version: 1.6.0 + resolution: "@backstage/core-plugin-api@npm:1.6.0" 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: + "@backstage/config": ^1.1.0 + "@backstage/types": ^1.1.1 + "@backstage/version-bridge": ^1.0.5 "@types/react": ^16.13.1 || ^17.0.0 + history: ^5.0.0 + i18next: ^22.4.15 + prop-types: ^15.7.2 + 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: 8308c1b90247911f6cf22963b530cef169287f508ff29d159d0c83758134dd43bd5acd2113350690a46a02246bc05dca975bcc38325000aefb1c93c80e2f19c7 + checksum: 540deb91d3c143ce1c3736359c3301af64fbd6eccbaae61bfc96f4e180654e7eb025bb1d4ff5be62b7ea3d6dac7ed617e4dba0c176cfdbf865400fde0f987ddb languageName: node linkType: hard -"@backstage/core-plugin-api@^1.3.0, @backstage/core-plugin-api@^1.5.0, @backstage/core-plugin-api@^1.5.3, @backstage/core-plugin-api@workspace:^, @backstage/core-plugin-api@workspace:packages/core-plugin-api": +"@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" dependencies: @@ -4199,7 +4273,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/errors@^1.1.5, @backstage/errors@workspace:^, @backstage/errors@workspace:packages/errors": +"@backstage/errors@^1.1.5, @backstage/errors@^1.2.2, @backstage/errors@workspace:^, @backstage/errors@workspace:packages/errors": version: 0.0.0-use.local resolution: "@backstage/errors@workspace:packages/errors" dependencies: @@ -4284,7 +4358,29 @@ __metadata: languageName: unknown linkType: soft -"@backstage/integration-react@^1.1.18, @backstage/integration-react@workspace:^, @backstage/integration-react@workspace:packages/integration-react": +"@backstage/integration-react@npm:^1.1.18": + version: 1.1.19 + resolution: "@backstage/integration-react@npm:1.1.19" + dependencies: + "@backstage/config": ^1.1.0 + "@backstage/core-components": ^0.13.5 + "@backstage/core-plugin-api": ^1.6.0 + "@backstage/integration": ^1.7.0 + "@backstage/theme": ^0.4.2 + "@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 + 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: 8ef2b46bf91b71351aa4b114de147d130e0298d8849cf2fa358ac1559c2026ffbfad10b15f6fa4bf94c7bbb4f4419766c6c66b77d2859fe184a43351f1f5df81 + languageName: node + linkType: hard + +"@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: @@ -4313,6 +4409,23 @@ __metadata: languageName: unknown linkType: soft +"@backstage/integration@npm:^1.7.0": + version: 1.7.0 + resolution: "@backstage/integration@npm:1.7.0" + dependencies: + "@azure/identity": ^3.2.1 + "@backstage/config": ^1.1.0 + "@backstage/errors": ^1.2.2 + "@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: f02516b7bdb7adb0516b49b90802e588f09c43b4db66bcce68314518c46b9c6fb8ca76ac7a55d4a80cdd414bb6876475b42eb6256b2efda9824ad3667ffa8f54 + languageName: node + linkType: hard + "@backstage/integration@workspace:^, @backstage/integration@workspace:packages/integration": version: 0.0.0-use.local resolution: "@backstage/integration@workspace:packages/integration" @@ -5647,7 +5760,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-catalog-common@^1.0.10, @backstage/plugin-catalog-common@workspace:^, @backstage/plugin-catalog-common@workspace:plugins/catalog-common": +"@backstage/plugin-catalog-common@^1.0.10, @backstage/plugin-catalog-common@^1.0.16, @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: @@ -5784,7 +5897,44 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-catalog-react@^1.2.4, @backstage/plugin-catalog-react@^1.8.3, @backstage/plugin-catalog-react@workspace:^, @backstage/plugin-catalog-react@workspace:plugins/catalog-react": +"@backstage/plugin-catalog-react@npm:^1.2.4, @backstage/plugin-catalog-react@npm:^1.8.3, @backstage/plugin-catalog-react@npm:^1.8.4": + version: 1.8.4 + resolution: "@backstage/plugin-catalog-react@npm:1.8.4" + dependencies: + "@backstage/catalog-client": ^1.4.4 + "@backstage/catalog-model": ^1.4.2 + "@backstage/core-components": ^0.13.5 + "@backstage/core-plugin-api": ^1.6.0 + "@backstage/errors": ^1.2.2 + "@backstage/integration": ^1.7.0 + "@backstage/plugin-catalog-common": ^1.0.16 + "@backstage/plugin-permission-common": ^0.7.8 + "@backstage/plugin-permission-react": ^0.4.15 + "@backstage/theme": ^0.4.2 + "@backstage/types": ^1.1.1 + "@backstage/version-bridge": ^1.0.5 + "@material-ui/core": ^4.12.2 + "@material-ui/icons": ^4.9.1 + "@material-ui/lab": 4.0.0-alpha.61 + "@react-hookz/web": ^23.0.0 + "@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: 6434741a60e4f53604a958c121d283d3d8b2756e1013d3a9b32659ae41b58359cbc3bee0791a95a35c847f43a76de9f9d2ea1f8e5fa6697adfc9115b5042a57e + languageName: node + linkType: hard + +"@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: @@ -7145,6 +7295,24 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-home-react@npm:^0.1.3": + version: 0.1.3 + resolution: "@backstage/plugin-home-react@npm:0.1.3" + dependencies: + "@backstage/core-components": ^0.13.5 + "@backstage/core-plugin-api": ^1.6.0 + "@material-ui/core": ^4.12.2 + "@material-ui/icons": ^4.9.1 + "@rjsf/utils": 5.13.0 + "@types/react": ^16.13.1 || ^17.0.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: e87c9fd44c65aa1a768555812f32f42b1d2dc7ab1097c283cae37105d1f17a7b1b198c85d39d72258551015161f317c8e4538a652f6e8ebe9800c3a365f6ebc3 + languageName: node + linkType: hard + "@backstage/plugin-home-react@workspace:^, @backstage/plugin-home-react@workspace:plugins/home-react": version: 0.0.0-use.local resolution: "@backstage/plugin-home-react@workspace:plugins/home-react" @@ -7173,7 +7341,39 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-home@^0.5.7, @backstage/plugin-home@workspace:^, @backstage/plugin-home@workspace:plugins/home": +"@backstage/plugin-home@npm:^0.5.7": + version: 0.5.8 + resolution: "@backstage/plugin-home@npm:0.5.8" + dependencies: + "@backstage/catalog-model": ^1.4.2 + "@backstage/config": ^1.1.0 + "@backstage/core-components": ^0.13.5 + "@backstage/core-plugin-api": ^1.6.0 + "@backstage/plugin-catalog-react": ^1.8.4 + "@backstage/plugin-home-react": ^0.1.3 + "@backstage/theme": ^0.4.2 + "@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.13.0" + "@rjsf/material-ui-v5": "npm:@rjsf/material-ui@5.13.0" + "@rjsf/utils": 5.13.0 + "@rjsf/validator-ajv8": 5.13.0 + "@types/react": ^16.13.1 || ^17.0.0 + lodash: ^4.17.21 + 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: 4f895b3a7e7f61149ba7b8fd6ec998d1f83b6e5262073893c5863fe79c46e5e2f52b43346f310733e04815aaebd82b8a13d34616e8d0848f60f87b1fb3193d60 + languageName: node + linkType: hard + +"@backstage/plugin-home@workspace:^, @backstage/plugin-home@workspace:plugins/home": version: 0.0.0-use.local resolution: "@backstage/plugin-home@workspace:plugins/home" dependencies: @@ -8030,7 +8230,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-permission-common@workspace:^, @backstage/plugin-permission-common@workspace:plugins/permission-common": +"@backstage/plugin-permission-common@^0.7.8, @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: @@ -8068,6 +8268,25 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-permission-react@npm:^0.4.15": + version: 0.4.15 + resolution: "@backstage/plugin-permission-react@npm:0.4.15" + dependencies: + "@backstage/config": ^1.1.0 + "@backstage/core-plugin-api": ^1.6.0 + "@backstage/plugin-permission-common": ^0.7.8 + "@types/react": ^16.13.1 || ^17.0.0 + cross-fetch: ^3.1.5 + react-use: ^17.2.4 + swr: ^2.0.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: 5f11264a7d46bee0924b9a00133e756e38d3cce5ce842104546963e08b8bfc6445e28ac4b2b75878fd5407631353e964e5f0b399bc958a76aaa732741b80a52a + languageName: node + linkType: hard + "@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" @@ -9798,7 +10017,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/theme@^0.4.1, @backstage/theme@workspace:^, @backstage/theme@workspace:packages/theme": +"@backstage/theme@^0.4.1, @backstage/theme@^0.4.2, @backstage/theme@workspace:^, @backstage/theme@workspace:packages/theme": version: 0.0.0-use.local resolution: "@backstage/theme@workspace:packages/theme" dependencies: @@ -9827,7 +10046,7 @@ __metadata: languageName: node linkType: hard -"@backstage/types@^1.0.2, @backstage/types@workspace:^, @backstage/types@workspace:packages/types": +"@backstage/types@^1.0.2, @backstage/types@^1.1.1, @backstage/types@workspace:^, @backstage/types@workspace:packages/types": version: 0.0.0-use.local resolution: "@backstage/types@workspace:packages/types" dependencies: @@ -9838,7 +10057,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/version-bridge@^1.0.3, @backstage/version-bridge@workspace:^, @backstage/version-bridge@workspace:packages/version-bridge": +"@backstage/version-bridge@^1.0.3, @backstage/version-bridge@^1.0.5, @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: From 817f2acbb18b9e4b559f1c5c8c9ce3936efbf354 Mon Sep 17 00:00:00 2001 From: ivgo Date: Tue, 26 Sep 2023 15:49:36 +0200 Subject: [PATCH 080/110] Make sure a default factory badge is selected Signed-off-by: ivgo --- .changeset/many-swans-eat.md | 5 +++++ plugins/badges-backend/src/plugin.ts | 2 ++ plugins/badges-backend/src/service/router.ts | 5 ++++- 3 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 .changeset/many-swans-eat.md diff --git a/.changeset/many-swans-eat.md b/.changeset/many-swans-eat.md new file mode 100644 index 0000000000..86580d7cfe --- /dev/null +++ b/.changeset/many-swans-eat.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-badges-backend': patch +--- + +Make sure the default badge factory is used if nothing is defined diff --git a/plugins/badges-backend/src/plugin.ts b/plugins/badges-backend/src/plugin.ts index 3e462e88e9..e5a51d763f 100644 --- a/plugins/badges-backend/src/plugin.ts +++ b/plugins/badges-backend/src/plugin.ts @@ -20,6 +20,7 @@ import { createBackendPlugin, } from '@backstage/backend-plugin-api'; import { createRouter } from './service/router'; +import { createDefaultBadgeFactories } from './badges'; /** * Badges backend plugin @@ -50,6 +51,7 @@ export const badgesPlugin = createBackendPlugin({ await createRouter({ config, logger: loggerToWinstonLogger(logger), + badgeFactories: createDefaultBadgeFactories(), discovery, tokenManager, identity, diff --git a/plugins/badges-backend/src/service/router.ts b/plugins/badges-backend/src/service/router.ts index 308865b73a..47bb8fcbe8 100644 --- a/plugins/badges-backend/src/service/router.ts +++ b/plugins/badges-backend/src/service/router.ts @@ -32,6 +32,7 @@ import { Logger } from 'winston'; import { IdentityApi } from '@backstage/plugin-auth-node'; import { getBearerTokenFromAuthorizationHeader } from '@backstage/plugin-auth-node'; import { BadgesStore, DatabaseBadgesStore } from '../database/badgesStore'; +import { createDefaultBadgeFactories } from '../badges'; /** @public */ export interface RouterOptions { @@ -54,7 +55,9 @@ export async function createRouter( options.catalog || new CatalogClient({ discoveryApi: options.discovery }); const badgeBuilder = options.badgeBuilder || - new DefaultBadgeBuilder(options.badgeFactories || {}); + new DefaultBadgeBuilder( + options.badgeFactories || createDefaultBadgeFactories(), + ); const router = Router(); const { config, logger, tokenManager, discovery, identity } = options; From 5c659b100d89d9f6791b22a18ebfba7dd8dbeaec Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 26 Sep 2023 15:34:52 +0000 Subject: [PATCH 081/110] chore(deps): update dependency @types/express-serve-static-core to v4.17.37 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index c1887a4ea0..bbb1bad8cc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17311,14 +17311,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.36 - resolution: "@types/express-serve-static-core@npm:4.17.36" + version: 4.17.37 + resolution: "@types/express-serve-static-core@npm:4.17.37" dependencies: "@types/node": "*" "@types/qs": "*" "@types/range-parser": "*" "@types/send": "*" - checksum: 410b13cbd663f18c0f8729e7f2ff54d960d96de76ebbae7cadb612972f85cc66c54051e00d32f11aa230c0a683d81a6d6fc7f7e4e383a95c0801494c517f36e1 + checksum: 2dab1380e45eb44e56ecc1be1c42c4b897364d2f2a08e03ca28fbcb1e6866e390217385435813711c046f9acd684424d088855dc32825d5cbecf72c60ecd037f languageName: node linkType: hard From 844c860a79b9d983eae56a9890e12465a20c59ae Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 26 Sep 2023 15:35:27 +0000 Subject: [PATCH 082/110] chore(deps): update dependency @types/lodash to v4.14.199 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index c1887a4ea0..e516a35f48 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17708,9 +17708,9 @@ __metadata: linkType: hard "@types/lodash@npm:^4.14.151, @types/lodash@npm:^4.14.173, @types/lodash@npm:^4.14.175": - version: 4.14.198 - resolution: "@types/lodash@npm:4.14.198" - checksum: b290e4480707151bcec738bca40527915defe52a0d8e26c83685c674163a265e1a88cb2ee56b0fb587a89819d0cd5df86ada836aec3e9c2e4bf516e7d348d524 + version: 4.14.199 + resolution: "@types/lodash@npm:4.14.199" + checksum: e68d1fcbbfce953ed87b296a628573f62939227bcda0c934954e862b421e8a34c5e71cad6fea27b9980567909e6a4698f09025692958e36d64ea9ed99ec6fb2e languageName: node linkType: hard From 37853ce61027048b8fbeb0fec1437ae84c1c32d9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 26 Sep 2023 15:35:58 +0000 Subject: [PATCH 083/110] chore(deps): update dependency @types/ndjson to v2.0.2 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index c1887a4ea0..9396fa675f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17838,12 +17838,12 @@ __metadata: linkType: hard "@types/ndjson@npm:^2.0.1": - version: 2.0.1 - resolution: "@types/ndjson@npm:2.0.1" + version: 2.0.2 + resolution: "@types/ndjson@npm:2.0.2" dependencies: "@types/node": "*" "@types/through": "*" - checksum: d7e5ef9d43424851d1d3e1b223c0d6508bf283c4a769eb08312a96b1e6e60011b3454a5599dbecfdad4128f7c9c6c1b5b4abfabe29bb5065d412dead1c20f9e8 + checksum: 2f4d60229a01dadd4ed1d7df923223788cc4517a15d0fc07b56b3dbdefb567646334e173d7f976a8a7ce7b85df74bf78fd8805f41bdd9ebd8d135310f472a2cb languageName: node linkType: hard From cdc326d2449b8c2342c896d045d7edadde6088d8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 26 Sep 2023 17:21:27 +0000 Subject: [PATCH 084/110] chore(deps): update dependency @types/archiver to v5.3.3 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index c1887a4ea0..16e275bebc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16785,11 +16785,11 @@ __metadata: linkType: hard "@types/archiver@npm:^5.1.0, @types/archiver@npm:^5.3.1": - version: 5.3.2 - resolution: "@types/archiver@npm:5.3.2" + version: 5.3.3 + resolution: "@types/archiver@npm:5.3.3" dependencies: "@types/readdir-glob": "*" - checksum: 9db5b4fdc1740fa07d08340ed827598cc6eda97406ac18a06a158670c7124d4120650a3b9cd660e9e39b42f033cf8f052566da32681e8ad91163473df88a3c4c + checksum: e660465ac9a622570ddbad86a306c7234c3272cb28eafe9c3ad7229f06e499dfadae9f0cb0caf41443318eea559b75ef662ea276ae64f19695e72018dae37ee7 languageName: node linkType: hard From 67a0339fd2ab2234ad2b6f51f12405e88ade8f1d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 26 Sep 2023 17:22:16 +0000 Subject: [PATCH 085/110] chore(deps): update dependency @types/d3-selection to v3.0.7 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index c1887a4ea0..db7d01597e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17153,9 +17153,9 @@ __metadata: linkType: hard "@types/d3-selection@npm:*, @types/d3-selection@npm:^3.0.1": - version: 3.0.6 - resolution: "@types/d3-selection@npm:3.0.6" - checksum: 01f9f3a41b98280947109911bcc6ebffff5c8c3e617695979c04ef9beef445a8cdc48a9fbdb3c9cff45a7345e83e8a5d6b346d7ceedca6ebc11dfd9717dbff6b + version: 3.0.7 + resolution: "@types/d3-selection@npm:3.0.7" + checksum: 715a0c7a78732650ae70b3487b3b6432b063482c1937bcd52c8b7a201563103170fdaa1f8c0ace882062521ac009f07fefb41198c8c43c5d3c518f8368c459d6 languageName: node linkType: hard From d9a53a977beda91bb9a375da3aca23f33a6b86ca Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 26 Sep 2023 17:23:04 +0000 Subject: [PATCH 086/110] chore(deps): update dependency @types/d3-zoom to v3.0.5 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index c1887a4ea0..73acf65140 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17192,12 +17192,12 @@ __metadata: linkType: hard "@types/d3-zoom@npm:^3.0.1": - version: 3.0.4 - resolution: "@types/d3-zoom@npm:3.0.4" + version: 3.0.5 + resolution: "@types/d3-zoom@npm:3.0.5" dependencies: "@types/d3-interpolate": "*" "@types/d3-selection": "*" - checksum: 6330b8411822b979ab0fd5a7a7755295377b4dfc61fd8f925d97e5b388e3dd604b455c0009b0eda3320c14c4ea367f740a04991a71d35befdca5f75218492a68 + checksum: acff15a30b2b81a99b46692c7aacc110c635a272e8d7e87af6aa5a01ebe9ebcafcaf475399d79ec73461a5ef037041dade49a6371d7587b759710123539b81b0 languageName: node linkType: hard From 17a0b98ab25c61e3b187ee7c2471093c375c39b8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 26 Sep 2023 17:23:58 +0000 Subject: [PATCH 087/110] chore(deps): update dependency @types/dagre to v0.7.50 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index c1887a4ea0..f7afb150a1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17202,9 +17202,9 @@ __metadata: linkType: hard "@types/dagre@npm:^0.7.44": - version: 0.7.49 - resolution: "@types/dagre@npm:0.7.49" - checksum: cb27683074f8c89c073d0b7b549692b67ddae7225a2b6f9586d75c11598f7bd32d9246ecb184017a55592e7daaf63e4d33dcbc56ca4c3999cf34352460ddf772 + version: 0.7.50 + resolution: "@types/dagre@npm:0.7.50" + checksum: a128048b5202c501a4595bbc17288aafbef90f3535e79385ddaf0842237e69aa5998dbc12bc2867244eefe3fb6c5026d9785bfdedea46d813f006066e06e8f44 languageName: node linkType: hard From febe2680d901cb3bd7be105bc301626b00ff6825 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 26 Sep 2023 17:24:51 +0000 Subject: [PATCH 088/110] chore(deps): update dependency @types/diff to v5.0.5 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index c1887a4ea0..dfb88a4f34 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17218,9 +17218,9 @@ __metadata: linkType: hard "@types/diff@npm:^5.0.0": - version: 5.0.4 - resolution: "@types/diff@npm:5.0.4" - checksum: 58f8c3e9c8ed40e97fc8039af95d8f12a620e9facf351273906612ad795678c3f64309e0ce29b03bce8e04a2913f0e6bc5cf2289821bdd312b99f1220025f90a + version: 5.0.5 + resolution: "@types/diff@npm:5.0.5" + checksum: 5f093341d5488cd33079400d4b2ff463dfd4f589bf0a54fbb25f7c87a7bdc16bd1e6125f252c081fa9a3ad44fc78b156c0a5f38bd8128edceb40ba084e051885 languageName: node linkType: hard From a2dbd371cb60e399dbafcaabccba1b22a9e3aa32 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 26 Sep 2023 17:25:38 +0000 Subject: [PATCH 089/110] chore(deps): update dependency @types/event-source-polyfill to v1.0.2 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index c1887a4ea0..75844e200a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17297,9 +17297,9 @@ __metadata: linkType: hard "@types/event-source-polyfill@npm:^1.0.0": - version: 1.0.1 - resolution: "@types/event-source-polyfill@npm:1.0.1" - checksum: 37f3ccc40e2fc43230047c3323f8bfc55f6ed40aee8c61af7f6b702a923be5615362cf3241f5a536f9c64932309a2184a0181bb48e105a94b968b8321cae1c60 + version: 1.0.2 + resolution: "@types/event-source-polyfill@npm:1.0.2" + checksum: f0813edfee0af768e6e0994b48f9f618df7a5d9023c383a8f35e9e805dec560222dc40fc583d5f1404977febb7353c27c1d0606c67d948a2d18634c18ae437a9 languageName: node linkType: hard From 2d8151061cd35857d9cc6af15f2d106c39d665f8 Mon Sep 17 00:00:00 2001 From: Matthew Clarke Date: Tue, 26 Sep 2023 18:40:10 -0400 Subject: [PATCH 090/110] refactor: Refactors the Kubernetes plugin in line with ADR11 (#19446) * refactor: k8s plugins Signed-off-by: Matthew Clarke * chore: move more files Signed-off-by: Matthew Clarke * chore: fix Signed-off-by: Matthew Clarke * fix: tsc Signed-off-by: Matthew Clarke * chore: changeset Signed-off-by: Matthew Clarke * chore: api report Signed-off-by: Matthew Clarke * fix: catalog Signed-off-by: Matthew Clarke * fix: types Signed-off-by: Matthew Clarke * fix: update lock Signed-off-by: Matthew Clarke --------- Signed-off-by: Matthew Clarke --- .changeset/spicy-chairs-film.md | 7 + plugins/kubernetes-common/api-report.md | 119 + plugins/kubernetes-common/package.json | 13 +- .../__fixtures__/deploy-bad.json | 0 .../__fixtures__/deploy-healthy.json | 0 .../__fixtures__/hpa-healthy.json | 0 .../__fixtures__/hpa-maxed-out.json | 0 .../__fixtures__/pod-crashing.json | 0 .../__fixtures__/pod-missing-cm.json | 0 .../error-detection}/__fixtures__/pod.json | 0 .../src/error-detection/common.ts | 0 .../src/error-detection/deployments.ts | 0 .../error-detection/error-detection.test.ts | 0 .../src/error-detection/error-detection.ts | 2 +- .../src/error-detection/hpas.ts | 0 .../src/error-detection/index.ts | 18 + .../src/error-detection/pods.ts | 0 .../src/error-detection/types.ts | 8 +- plugins/kubernetes-common/src/index.ts | 2 + plugins/kubernetes-common/src/types.ts | 19 + .../src/util}/index.ts | 3 +- .../src/util}/response.ts | 5 +- plugins/kubernetes-react/.eslintrc.js | 1 + plugins/kubernetes-react/README.md | 5 + plugins/kubernetes-react/api-report.md | 751 +++ plugins/kubernetes-react/catalog-info.yaml | 11 + plugins/kubernetes-react/package.json | 66 + .../src/__fixtures__/1-cronjobs.json | 446 ++ .../src/__fixtures__/1-deployments.json | 2911 +++++++++++ .../src/__fixtures__/1-statefulsets.json | 2912 +++++++++++ .../src/__fixtures__/2-cronjobs.json | 385 ++ .../src/__fixtures__/2-deployments.json | 4519 ++++++++++++++++ .../src/__fixtures__/2-statefulsets.json | 4521 +++++++++++++++++ .../src/api/KubernetesBackendClient.test.ts | 0 .../src/api/KubernetesBackendClient.ts | 1 + .../src/api/KubernetesProxyClient.test.ts | 0 .../src/api/KubernetesProxyClient.ts | 0 .../src/api/index.ts | 0 .../src/api/types.ts | 4 + .../src/components/Cluster/Cluster.test.tsx | 0 .../src/components/Cluster/Cluster.tsx | 14 +- .../src/components/Cluster}/index.ts | 2 +- .../CronJobsAccordions.test.tsx | 0 .../CronJobsAccordions/CronJobsAccordions.tsx | 12 +- .../CronJobsDrawer.test.tsx | 0 .../CronJobsAccordions/CronJobsDrawer.tsx | 0 .../components/CronJobsAccordions}/index.ts | 2 +- .../ArgoRollouts/Rollout.test.tsx | 0 .../CustomResources/ArgoRollouts/Rollout.tsx | 0 .../ArgoRollouts/RolloutDrawer.tsx | 0 .../ArgoRollouts/StepsProgress.test.tsx | 0 .../ArgoRollouts/StepsProgress.tsx | 0 .../__fixtures__/aborted-rollout.json | 0 .../__fixtures__/analysis-steps.ts | 0 .../__fixtures__/grouped-resources.json | 0 .../ArgoRollouts/__fixtures__/pause-steps.ts | 0 .../__fixtures__/paused-rollout.json | 0 .../ArgoRollouts/__fixtures__/rollout.json | 0 .../__fixtures__/setweight-steps.ts | 0 .../CustomResources/ArgoRollouts/index.ts | 0 .../CustomResources/ArgoRollouts/types.ts | 0 .../CustomResources/CustomResources.tsx | 12 +- .../DefaultCustomResource.test.tsx | 0 .../CustomResources/DefaultCustomResource.tsx | 0 .../DefaultCustomResourceDrawer.tsx | 0 .../__fixtures__/analysis-run.json | 0 .../src/components/CustomResources}/index.ts | 2 +- .../DeploymentDrawer.test.tsx | 0 .../DeploymentDrawer.tsx | 0 .../DeploymentsAccordions.test.tsx | 0 .../DeploymentsAccordions.tsx | 0 .../components/DeploymentsAccordions/index.ts | 0 .../components/ErrorPanel/ErrorPanel.test.tsx | 0 .../src/components/ErrorPanel/ErrorPanel.tsx | 12 +- .../src/components/ErrorPanel}/index.ts | 2 +- .../ErrorReporting/ErrorReporting.tsx | 17 +- .../src/components/ErrorReporting/index.ts | 16 + .../HorizontalPodAutoscalerDrawer.test.tsx | 0 .../HorizontalPodAutoscalerDrawer.tsx | 0 .../horizontalpodautoscalers.json | 0 .../HorizontalPodAutoscalers/index.ts | 0 .../IngressDrawer.test.tsx | 0 .../IngressesAccordions/IngressDrawer.tsx | 0 .../IngressesAccordions.test.tsx | 0 .../IngressesAccordions.tsx | 13 +- .../__fixtures__/2-ingresses.json | 0 .../components/IngressesAccordions/index.ts | 16 + .../JobsAccordions/JobsAccordions.test.tsx | 0 .../JobsAccordions/JobsAccordions.tsx | 12 +- .../JobsAccordions/JobsDrawer.test.tsx | 0 .../components/JobsAccordions/JobsDrawer.tsx | 0 .../src/components/JobsAccordions}/index.ts | 2 +- .../KubernetesDrawer/KubernetesDrawer.tsx | 21 +- ...ubernetesStructuredMetadataTableDrawer.tsx | 35 +- .../KubernetesDrawer/ManifestYaml.tsx | 10 + .../src/components/KubernetesDrawer/index.ts | 1 + .../PodExecTerminal/PodExecTerminal.test.tsx | 0 .../PodExecTerminal/PodExecTerminal.tsx | 2 +- .../PodExecTerminalAttachAddon.ts | 0 .../PodExecTerminal/PodExecTerminalDialog.tsx | 0 .../src/components/PodExecTerminal/index.ts | 0 .../PodExecTerminal/matchMedia.mock.ts | 0 .../Pods/ErrorList/ErrorList.test.tsx | 2 +- .../components/Pods/ErrorList/ErrorList.tsx | 0 .../src/components/Pods/ErrorList/index.ts | 0 .../components/Pods/Events/Events.test.tsx | 0 .../src/components/Pods/Events/Events.tsx | 0 .../src/components/Pods/Events/index.ts | 0 .../components/Pods/Events/useEvents.test.tsx | 0 .../src/components/Pods/Events/useEvents.ts | 2 +- .../Pods/FixDialog/FixDialog.test.tsx | 0 .../components/Pods/FixDialog/FixDialog.tsx | 2 +- .../src/components/Pods/FixDialog/index.ts | 0 .../Pods/PodDrawer/ContainerCard.test.tsx | 0 .../Pods/PodDrawer/ContainerCard.tsx | 0 .../Pods/PodDrawer/PendingPodContent.test.tsx | 0 .../Pods/PodDrawer/PendingPodContent.tsx | 0 .../Pods/PodDrawer/PodDrawer.test.tsx | 0 .../components/Pods/PodDrawer/PodDrawer.tsx | 2 +- .../src/components/Pods/PodDrawer/index.ts | 0 .../src/components/Pods/PodLogs/PodLogs.tsx | 0 .../components/Pods/PodLogs/PodLogsDialog.tsx | 0 .../src/components/Pods/PodLogs/index.ts | 0 .../src/components/Pods/PodLogs/types.ts | 0 .../src/components/Pods/PodLogs/usePodLogs.ts | 2 +- .../src/components/Pods/PodsTable.test.tsx | 0 .../src/components/Pods/PodsTable.tsx | 29 +- .../Pods/__fixtures__/crashing-pod.json | 0 .../components/Pods}/__fixtures__/pod.json | 0 .../src/components/Pods/index.ts | 2 +- .../src/components/Pods/types.ts | 2 +- .../ResourceUtilization.test.tsx | 0 .../ResourceUtilization.tsx | 3 +- .../components/ResourceUtilization/index.ts | 2 +- .../ServicesAccordions/ServiceDrawer.test.tsx | 0 .../ServicesAccordions/ServiceDrawer.tsx | 0 .../ServicesAccordions.test.tsx | 0 .../ServicesAccordions/ServicesAccordions.tsx | 12 +- .../__fixtures__/2-services.json | 0 .../components/ServicesAccordions/index.ts | 16 + .../StatefulSetDrawer.test.tsx | 0 .../StatefulSetDrawer.tsx | 0 .../StatefulSetsAccordions.test.tsx | 0 .../StatefulSetsAccordions.tsx | 0 .../StatefulSetsAccordions/index.ts | 0 .../src/components/index.ts | 1 - .../src/hooks/Cluster.ts | 3 + .../src/hooks/GroupedResponses.ts | 7 +- .../src/hooks/PodNamesWithErrors.ts | 3 + .../src/hooks/PodNamesWithMetrics.ts | 4 +- .../useIsPodExecTerminalSupported.ts | 0 .../src/hooks/auth.test.ts | 0 .../src/hooks/auth.ts | 4 +- .../src/hooks/index.ts | 0 .../src/hooks/test-utils.tsx | 0 .../src/hooks/types.ts | 0 .../src/hooks/useCustomResources.test.ts | 0 .../src/hooks/useCustomResources.ts | 4 +- .../useIsPodExecTerminalSupported.test.ts | 0 .../hooks/useIsPodExecTerminalSupported.ts | 3 +- .../src/hooks/useKubernetesObjects.test.ts | 0 .../src/hooks/useKubernetesObjects.ts | 12 +- .../src/hooks/useMatchingErrors.test.tsx | 6 +- .../src/hooks/useMatchingErrors.ts | 5 +- .../src/hooks/usePodMetrics.test.tsx | 0 .../src/hooks/usePodMetrics.ts | 4 +- plugins/kubernetes-react/src/index.ts | 29 + .../AksKubernetesAuthProvider.ts | 1 + .../GoogleKubernetesAuthProvider.ts | 1 + .../KubernetesAuthProviders.test.ts | 0 .../KubernetesAuthProviders.ts | 1 + .../OidcKubernetesAuthProvider.ts | 1 + .../ServerSideAuthProvider.ts | 0 .../src/kubernetes-auth-provider}/index.ts | 13 +- .../src/kubernetes-auth-provider/types.ts | 3 + plugins/kubernetes-react/src/setupTests.ts | 16 + .../src/types/index.ts | 0 plugins/kubernetes-react/src/types/types.ts | 28 + .../clusterLinks/formatClusterLink.test.ts | 0 .../utils/clusterLinks/formatClusterLink.ts | 2 + .../utils/clusterLinks/formatters/aks.test.ts | 0 .../src/utils/clusterLinks/formatters/aks.ts | 0 .../utils/clusterLinks/formatters/eks.test.ts | 0 .../src/utils/clusterLinks/formatters/eks.ts | 0 .../utils/clusterLinks/formatters/gke.test.ts | 0 .../src/utils/clusterLinks/formatters/gke.ts | 0 .../utils/clusterLinks/formatters/index.ts | 0 .../clusterLinks/formatters/openshift.test.ts | 0 .../clusterLinks/formatters/openshift.ts | 0 .../clusterLinks/formatters/rancher.test.ts | 0 .../utils/clusterLinks/formatters/rancher.ts | 0 .../clusterLinks/formatters/standard.test.ts | 0 .../utils/clusterLinks/formatters/standard.ts | 0 .../src/utils/clusterLinks/index.ts | 0 .../src/utils/crons.test.ts | 0 .../src/utils/crons.ts | 0 .../src/utils/index.ts | 0 .../src/utils/owner.test.ts | 0 .../src/utils/owner.ts | 0 .../src/utils/pod.test.tsx | 0 .../src/utils/pod.tsx | 0 .../src/utils/resources.ts | 0 plugins/kubernetes/api-report.md | 764 +-- plugins/kubernetes/package.json | 1 + .../KubernetesContent.test.tsx | 14 +- .../{components => }/KubernetesContent.tsx | 41 +- plugins/kubernetes/src/Router.tsx | 2 +- plugins/kubernetes/src/assets/emptystate.svg | 1 - .../components/IngressesAccordions/index.ts | 16 - .../components/ServicesAccordions/index.ts | 16 - plugins/kubernetes/src/index.ts | 9 +- .../src/kubernetes-auth-provider/index.ts | 21 - plugins/kubernetes/src/plugin.ts | 13 +- plugins/kubernetes/src/types/types.ts | 57 - yarn.lock | 127 +- 215 files changed, 17249 insertions(+), 992 deletions(-) create mode 100644 .changeset/spicy-chairs-film.md rename plugins/{kubernetes => kubernetes-common}/src/error-detection/__fixtures__/deploy-bad.json (100%) rename plugins/{kubernetes => kubernetes-common}/src/error-detection/__fixtures__/deploy-healthy.json (100%) rename plugins/{kubernetes => kubernetes-common}/src/error-detection/__fixtures__/hpa-healthy.json (100%) rename plugins/{kubernetes => kubernetes-common}/src/error-detection/__fixtures__/hpa-maxed-out.json (100%) rename plugins/{kubernetes => kubernetes-common}/src/error-detection/__fixtures__/pod-crashing.json (100%) rename plugins/{kubernetes => kubernetes-common}/src/error-detection/__fixtures__/pod-missing-cm.json (100%) rename plugins/{kubernetes/src/components/Pods => kubernetes-common/src/error-detection}/__fixtures__/pod.json (100%) rename plugins/{kubernetes => kubernetes-common}/src/error-detection/common.ts (100%) rename plugins/{kubernetes => kubernetes-common}/src/error-detection/deployments.ts (100%) rename plugins/{kubernetes => kubernetes-common}/src/error-detection/error-detection.test.ts (100%) rename plugins/{kubernetes => kubernetes-common}/src/error-detection/error-detection.ts (97%) rename plugins/{kubernetes => kubernetes-common}/src/error-detection/hpas.ts (100%) create mode 100644 plugins/kubernetes-common/src/error-detection/index.ts rename plugins/{kubernetes => kubernetes-common}/src/error-detection/pods.ts (100%) rename plugins/{kubernetes => kubernetes-common}/src/error-detection/types.ts (93%) rename plugins/{kubernetes/src/components/Cluster => kubernetes-common/src/util}/index.ts (94%) rename plugins/{kubernetes/src/utils => kubernetes-common/src/util}/response.ts (95%) create mode 100644 plugins/kubernetes-react/.eslintrc.js create mode 100644 plugins/kubernetes-react/README.md create mode 100644 plugins/kubernetes-react/api-report.md create mode 100644 plugins/kubernetes-react/catalog-info.yaml create mode 100644 plugins/kubernetes-react/package.json create mode 100644 plugins/kubernetes-react/src/__fixtures__/1-cronjobs.json create mode 100644 plugins/kubernetes-react/src/__fixtures__/1-deployments.json create mode 100644 plugins/kubernetes-react/src/__fixtures__/1-statefulsets.json create mode 100644 plugins/kubernetes-react/src/__fixtures__/2-cronjobs.json create mode 100644 plugins/kubernetes-react/src/__fixtures__/2-deployments.json create mode 100644 plugins/kubernetes-react/src/__fixtures__/2-statefulsets.json rename plugins/{kubernetes => kubernetes-react}/src/api/KubernetesBackendClient.test.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/api/KubernetesBackendClient.ts (99%) rename plugins/{kubernetes => kubernetes-react}/src/api/KubernetesProxyClient.test.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/api/KubernetesProxyClient.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/api/index.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/api/types.ts (97%) rename plugins/{kubernetes => kubernetes-react}/src/components/Cluster/Cluster.test.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/Cluster/Cluster.tsx (96%) rename plugins/{kubernetes/src/components/ErrorPanel => kubernetes-react/src/components/Cluster}/index.ts (93%) rename plugins/{kubernetes => kubernetes-react}/src/components/CronJobsAccordions/CronJobsAccordions.test.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/CronJobsAccordions/CronJobsAccordions.tsx (97%) rename plugins/{kubernetes => kubernetes-react}/src/components/CronJobsAccordions/CronJobsDrawer.test.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/CronJobsAccordions/CronJobsDrawer.tsx (100%) rename plugins/{kubernetes/src/components/JobsAccordions => kubernetes-react/src/components/CronJobsAccordions}/index.ts (92%) rename plugins/{kubernetes => kubernetes-react}/src/components/CustomResources/ArgoRollouts/Rollout.test.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/CustomResources/ArgoRollouts/Rollout.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/CustomResources/ArgoRollouts/RolloutDrawer.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/CustomResources/ArgoRollouts/StepsProgress.test.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/CustomResources/ArgoRollouts/StepsProgress.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/CustomResources/ArgoRollouts/__fixtures__/aborted-rollout.json (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/CustomResources/ArgoRollouts/__fixtures__/analysis-steps.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/CustomResources/ArgoRollouts/__fixtures__/grouped-resources.json (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/CustomResources/ArgoRollouts/__fixtures__/pause-steps.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/CustomResources/ArgoRollouts/__fixtures__/paused-rollout.json (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/CustomResources/ArgoRollouts/__fixtures__/rollout.json (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/CustomResources/ArgoRollouts/__fixtures__/setweight-steps.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/CustomResources/ArgoRollouts/index.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/CustomResources/ArgoRollouts/types.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/CustomResources/CustomResources.tsx (95%) rename plugins/{kubernetes => kubernetes-react}/src/components/CustomResources/DefaultCustomResource.test.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/CustomResources/DefaultCustomResource.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/CustomResources/DefaultCustomResourceDrawer.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/CustomResources/__fixtures__/analysis-run.json (100%) rename plugins/{kubernetes/src/components/ErrorReporting => kubernetes-react/src/components/CustomResources}/index.ts (92%) rename plugins/{kubernetes => kubernetes-react}/src/components/DeploymentsAccordions/DeploymentDrawer.test.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/DeploymentsAccordions/DeploymentDrawer.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/DeploymentsAccordions/DeploymentsAccordions.test.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/DeploymentsAccordions/DeploymentsAccordions.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/DeploymentsAccordions/index.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/ErrorPanel/ErrorPanel.test.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/ErrorPanel/ErrorPanel.tsx (96%) rename plugins/{kubernetes/src/components/CustomResources => kubernetes-react/src/components/ErrorPanel}/index.ts (91%) rename plugins/{kubernetes => kubernetes-react}/src/components/ErrorReporting/ErrorReporting.tsx (92%) create mode 100644 plugins/kubernetes-react/src/components/ErrorReporting/index.ts rename plugins/{kubernetes => kubernetes-react}/src/components/HorizontalPodAutoscalers/HorizontalPodAutoscalerDrawer.test.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/HorizontalPodAutoscalers/HorizontalPodAutoscalerDrawer.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/HorizontalPodAutoscalers/__fixtures__/horizontalpodautoscalers.json (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/HorizontalPodAutoscalers/index.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/IngressesAccordions/IngressDrawer.test.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/IngressesAccordions/IngressDrawer.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/IngressesAccordions/IngressesAccordions.test.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/IngressesAccordions/IngressesAccordions.tsx (96%) rename plugins/{kubernetes => kubernetes-react}/src/components/IngressesAccordions/__fixtures__/2-ingresses.json (100%) create mode 100644 plugins/kubernetes-react/src/components/IngressesAccordions/index.ts rename plugins/{kubernetes => kubernetes-react}/src/components/JobsAccordions/JobsAccordions.test.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/JobsAccordions/JobsAccordions.tsx (97%) rename plugins/{kubernetes => kubernetes-react}/src/components/JobsAccordions/JobsDrawer.test.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/JobsAccordions/JobsDrawer.tsx (100%) rename plugins/{kubernetes/src/components/CronJobsAccordions => kubernetes-react/src/components/JobsAccordions}/index.ts (91%) rename plugins/{kubernetes => kubernetes-react}/src/components/KubernetesDrawer/KubernetesDrawer.tsx (93%) rename plugins/{kubernetes => kubernetes-react}/src/components/KubernetesDrawer/KubernetesStructuredMetadataTableDrawer.tsx (95%) rename plugins/{kubernetes => kubernetes-react}/src/components/KubernetesDrawer/ManifestYaml.tsx (94%) rename plugins/{kubernetes => kubernetes-react}/src/components/KubernetesDrawer/index.ts (95%) rename plugins/{kubernetes => kubernetes-react}/src/components/PodExecTerminal/PodExecTerminal.test.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/PodExecTerminal/PodExecTerminal.tsx (99%) rename plugins/{kubernetes => kubernetes-react}/src/components/PodExecTerminal/PodExecTerminalAttachAddon.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/PodExecTerminal/PodExecTerminalDialog.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/PodExecTerminal/index.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/PodExecTerminal/matchMedia.mock.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/Pods/ErrorList/ErrorList.test.tsx (97%) rename plugins/{kubernetes => kubernetes-react}/src/components/Pods/ErrorList/ErrorList.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/Pods/ErrorList/index.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/Pods/Events/Events.test.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/Pods/Events/Events.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/Pods/Events/index.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/Pods/Events/useEvents.test.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/Pods/Events/useEvents.ts (95%) rename plugins/{kubernetes => kubernetes-react}/src/components/Pods/FixDialog/FixDialog.test.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/Pods/FixDialog/FixDialog.tsx (98%) rename plugins/{kubernetes => kubernetes-react}/src/components/Pods/FixDialog/index.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/Pods/PodDrawer/ContainerCard.test.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/Pods/PodDrawer/ContainerCard.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/Pods/PodDrawer/PendingPodContent.test.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/Pods/PodDrawer/PendingPodContent.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/Pods/PodDrawer/PodDrawer.test.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/Pods/PodDrawer/PodDrawer.tsx (99%) rename plugins/{kubernetes => kubernetes-react}/src/components/Pods/PodDrawer/index.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/Pods/PodLogs/PodLogs.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/Pods/PodLogs/PodLogsDialog.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/Pods/PodLogs/index.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/Pods/PodLogs/types.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/Pods/PodLogs/usePodLogs.ts (95%) rename plugins/{kubernetes => kubernetes-react}/src/components/Pods/PodsTable.test.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/Pods/PodsTable.tsx (96%) rename plugins/{kubernetes => kubernetes-react}/src/components/Pods/__fixtures__/crashing-pod.json (100%) rename plugins/{kubernetes/src/error-detection => kubernetes-react/src/components/Pods}/__fixtures__/pod.json (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/Pods/index.ts (94%) rename plugins/{kubernetes => kubernetes-react}/src/components/Pods/types.ts (92%) rename plugins/{kubernetes => kubernetes-react}/src/components/ResourceUtilization/ResourceUtilization.test.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/ResourceUtilization/ResourceUtilization.tsx (96%) rename plugins/{kubernetes => kubernetes-react}/src/components/ResourceUtilization/index.ts (90%) rename plugins/{kubernetes => kubernetes-react}/src/components/ServicesAccordions/ServiceDrawer.test.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/ServicesAccordions/ServiceDrawer.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/ServicesAccordions/ServicesAccordions.test.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/ServicesAccordions/ServicesAccordions.tsx (97%) rename plugins/{kubernetes => kubernetes-react}/src/components/ServicesAccordions/__fixtures__/2-services.json (100%) create mode 100644 plugins/kubernetes-react/src/components/ServicesAccordions/index.ts rename plugins/{kubernetes => kubernetes-react}/src/components/StatefulSetsAccordions/StatefulSetDrawer.test.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/StatefulSetsAccordions/StatefulSetDrawer.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/StatefulSetsAccordions/StatefulSetsAccordions.test.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/StatefulSetsAccordions/StatefulSetsAccordions.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/StatefulSetsAccordions/index.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/components/index.ts (96%) rename plugins/{kubernetes => kubernetes-react}/src/hooks/Cluster.ts (97%) rename plugins/{kubernetes => kubernetes-react}/src/hooks/GroupedResponses.ts (90%) rename plugins/{kubernetes => kubernetes-react}/src/hooks/PodNamesWithErrors.ts (97%) rename plugins/{kubernetes => kubernetes-react}/src/hooks/PodNamesWithMetrics.ts (97%) rename plugins/{kubernetes => kubernetes-react}/src/hooks/__mocks__/useIsPodExecTerminalSupported.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/hooks/auth.test.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/hooks/auth.ts (98%) rename plugins/{kubernetes => kubernetes-react}/src/hooks/index.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/hooks/test-utils.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/hooks/types.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/hooks/useCustomResources.test.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/hooks/useCustomResources.ts (99%) rename plugins/{kubernetes => kubernetes-react}/src/hooks/useIsPodExecTerminalSupported.test.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/hooks/useIsPodExecTerminalSupported.ts (96%) rename plugins/{kubernetes => kubernetes-react}/src/hooks/useKubernetesObjects.test.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/hooks/useKubernetesObjects.ts (97%) rename plugins/{kubernetes => kubernetes-react}/src/hooks/useMatchingErrors.test.tsx (95%) rename plugins/{kubernetes => kubernetes-react}/src/hooks/useMatchingErrors.ts (95%) rename plugins/{kubernetes => kubernetes-react}/src/hooks/usePodMetrics.test.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/hooks/usePodMetrics.ts (99%) create mode 100644 plugins/kubernetes-react/src/index.ts rename plugins/{kubernetes => kubernetes-react}/src/kubernetes-auth-provider/AksKubernetesAuthProvider.ts (98%) rename plugins/{kubernetes => kubernetes-react}/src/kubernetes-auth-provider/GoogleKubernetesAuthProvider.ts (99%) rename plugins/{kubernetes => kubernetes-react}/src/kubernetes-auth-provider/KubernetesAuthProviders.test.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/kubernetes-auth-provider/KubernetesAuthProviders.ts (99%) rename plugins/{kubernetes => kubernetes-react}/src/kubernetes-auth-provider/OidcKubernetesAuthProvider.ts (99%) rename plugins/{kubernetes => kubernetes-react}/src/kubernetes-auth-provider/ServerSideAuthProvider.ts (100%) rename plugins/{kubernetes/src/error-detection => kubernetes-react/src/kubernetes-auth-provider}/index.ts (70%) rename plugins/{kubernetes => kubernetes-react}/src/kubernetes-auth-provider/types.ts (96%) create mode 100644 plugins/kubernetes-react/src/setupTests.ts rename plugins/{kubernetes => kubernetes-react}/src/types/index.ts (100%) create mode 100644 plugins/kubernetes-react/src/types/types.ts rename plugins/{kubernetes => kubernetes-react}/src/utils/clusterLinks/formatClusterLink.test.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/utils/clusterLinks/formatClusterLink.ts (90%) rename plugins/{kubernetes => kubernetes-react}/src/utils/clusterLinks/formatters/aks.test.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/utils/clusterLinks/formatters/aks.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/utils/clusterLinks/formatters/eks.test.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/utils/clusterLinks/formatters/eks.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/utils/clusterLinks/formatters/gke.test.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/utils/clusterLinks/formatters/gke.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/utils/clusterLinks/formatters/index.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/utils/clusterLinks/formatters/openshift.test.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/utils/clusterLinks/formatters/openshift.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/utils/clusterLinks/formatters/rancher.test.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/utils/clusterLinks/formatters/rancher.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/utils/clusterLinks/formatters/standard.test.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/utils/clusterLinks/formatters/standard.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/utils/clusterLinks/index.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/utils/crons.test.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/utils/crons.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/utils/index.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/utils/owner.test.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/utils/owner.ts (100%) rename plugins/{kubernetes => kubernetes-react}/src/utils/pod.test.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/utils/pod.tsx (100%) rename plugins/{kubernetes => kubernetes-react}/src/utils/resources.ts (100%) rename plugins/kubernetes/src/{components => }/KubernetesContent.test.tsx (91%) rename plugins/kubernetes/src/{components => }/KubernetesContent.tsx (81%) delete mode 100644 plugins/kubernetes/src/assets/emptystate.svg delete mode 100644 plugins/kubernetes/src/components/IngressesAccordions/index.ts delete mode 100644 plugins/kubernetes/src/components/ServicesAccordions/index.ts delete mode 100644 plugins/kubernetes/src/kubernetes-auth-provider/index.ts delete mode 100644 plugins/kubernetes/src/types/types.ts diff --git a/.changeset/spicy-chairs-film.md b/.changeset/spicy-chairs-film.md new file mode 100644 index 0000000000..475d786330 --- /dev/null +++ b/.changeset/spicy-chairs-film.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-kubernetes-common': minor +'@backstage/plugin-kubernetes-react': minor +'@backstage/plugin-kubernetes': minor +--- + +Refactor Kubernetes plugins in line with ADR 11, no breaking changes yet diff --git a/plugins/kubernetes-common/api-report.md b/plugins/kubernetes-common/api-report.md index 051293f37f..0840278394 100644 --- a/plugins/kubernetes-common/api-report.md +++ b/plugins/kubernetes-common/api-report.md @@ -5,7 +5,9 @@ ```ts import { BasicPermission } from '@backstage/plugin-permission-common'; import { Entity } from '@backstage/catalog-model'; +import { FetchResponse as FetchResponse_2 } from '@backstage/plugin-kubernetes-common'; import type { JsonObject } from '@backstage/types'; +import { ObjectsByEntityResponse as ObjectsByEntityResponse_2 } from '@backstage/plugin-kubernetes-common'; import { PodStatus } from '@kubernetes/client-node'; import { V1ConfigMap } from '@kubernetes/client-node'; import { V1CronJob } from '@kubernetes/client-node'; @@ -174,6 +176,67 @@ export interface DeploymentFetchResponse { type: 'deployments'; } +// @public (undocumented) +export interface DeploymentResources { + // (undocumented) + deployments: V1Deployment[]; + // (undocumented) + horizontalPodAutoscalers: V1HorizontalPodAutoscaler[]; + // (undocumented) + pods: V1Pod[]; + // (undocumented) + replicaSets: V1ReplicaSet[]; +} + +// @public +export interface DetectedError { + // (undocumented) + message: string; + // (undocumented) + occurrenceCount: number; + // (undocumented) + proposedFix?: ProposedFix; + // (undocumented) + severity: ErrorSeverity; + // (undocumented) + sourceRef: ResourceRef; + // (undocumented) + type: string; +} + +// @public +export type DetectedErrorsByCluster = Map; + +// @public +export const detectErrors: ( + objects: ObjectsByEntityResponse_2, +) => DetectedErrorsByCluster; + +// @public (undocumented) +export interface DocsSolution extends ProposedFixBase { + // (undocumented) + docsLink: string; + // (undocumented) + type: 'docs'; +} + +// @public (undocumented) +export interface ErrorMapper { + // (undocumented) + detectErrors: (resource: T) => DetectedError[]; +} + +// @public +export type ErrorSeverity = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10; + +// @public (undocumented) +export interface EventsSolution extends ProposedFixBase { + // (undocumented) + podName: string; + // (undocumented) + type: 'events'; +} + // @public (undocumented) export type FetchResponse = | PodFetchResponse @@ -191,6 +254,29 @@ export type FetchResponse = | DaemonSetsFetchResponse | PodStatusFetchResponse; +// @public (undocumented) +export interface GroupedResponses extends DeploymentResources { + // (undocumented) + configMaps: V1ConfigMap[]; + // (undocumented) + cronJobs: V1CronJob[]; + // (undocumented) + customResources: any[]; + // (undocumented) + ingresses: V1Ingress[]; + // (undocumented) + jobs: V1Job[]; + // (undocumented) + services: V1Service[]; + // (undocumented) + statefulsets: V1StatefulSet[]; +} + +// @public (undocumented) +export const groupResponses: ( + fetchResponse: FetchResponse_2[], +) => GroupedResponses; + // @public (undocumented) export interface HorizontalPodAutoscalersFetchResponse { // (undocumented) @@ -251,6 +337,14 @@ export interface LimitRangeFetchResponse { type: 'limitranges'; } +// @public (undocumented) +export interface LogSolution extends ProposedFixBase { + // (undocumented) + container: string; + // (undocumented) + type: 'logs'; +} + // @public (undocumented) export interface ObjectsByEntityResponse { // (undocumented) @@ -273,6 +367,19 @@ export interface PodStatusFetchResponse { type: 'podstatus'; } +// @public (undocumented) +export type ProposedFix = LogSolution | DocsSolution | EventsSolution; + +// @public (undocumented) +export interface ProposedFixBase { + // (undocumented) + actions: string[]; + // (undocumented) + errorType: string; + // (undocumented) + rootCauseExplanation: string; +} + // @public (undocumented) export interface RawFetchError { // (undocumented) @@ -289,6 +396,18 @@ export interface ReplicaSetsFetchResponse { type: 'replicasets'; } +// @public +export interface ResourceRef { + // (undocumented) + apiGroup: string; + // (undocumented) + kind: string; + // (undocumented) + name: string; + // (undocumented) + namespace: string; +} + // @public (undocumented) export interface ServiceFetchResponse { // (undocumented) diff --git a/plugins/kubernetes-common/package.json b/plugins/kubernetes-common/package.json index b563cbff4e..99d38b803e 100644 --- a/plugins/kubernetes-common/package.json +++ b/plugins/kubernetes-common/package.json @@ -40,11 +40,20 @@ }, "dependencies": { "@backstage/catalog-model": "workspace:^", + "@backstage/core-plugin-api": "workspace:^", + "@backstage/errors": "workspace:^", "@backstage/plugin-permission-common": "workspace:^", - "@kubernetes/client-node": "0.18.1" + "@backstage/types": "workspace:^", + "@kubernetes/client-node": "0.18.1", + "kubernetes-models": "^4.3.1", + "lodash": "^4.17.21", + "luxon": "^3.0.0" }, "devDependencies": { - "@backstage/cli": "workspace:^" + "@backstage/cli": "workspace:^", + "@backstage/core-app-api": "workspace:^", + "@backstage/test-utils": "workspace:^", + "msw": "^1.3.1" }, "jest": { "roots": [ diff --git a/plugins/kubernetes/src/error-detection/__fixtures__/deploy-bad.json b/plugins/kubernetes-common/src/error-detection/__fixtures__/deploy-bad.json similarity index 100% rename from plugins/kubernetes/src/error-detection/__fixtures__/deploy-bad.json rename to plugins/kubernetes-common/src/error-detection/__fixtures__/deploy-bad.json diff --git a/plugins/kubernetes/src/error-detection/__fixtures__/deploy-healthy.json b/plugins/kubernetes-common/src/error-detection/__fixtures__/deploy-healthy.json similarity index 100% rename from plugins/kubernetes/src/error-detection/__fixtures__/deploy-healthy.json rename to plugins/kubernetes-common/src/error-detection/__fixtures__/deploy-healthy.json diff --git a/plugins/kubernetes/src/error-detection/__fixtures__/hpa-healthy.json b/plugins/kubernetes-common/src/error-detection/__fixtures__/hpa-healthy.json similarity index 100% rename from plugins/kubernetes/src/error-detection/__fixtures__/hpa-healthy.json rename to plugins/kubernetes-common/src/error-detection/__fixtures__/hpa-healthy.json diff --git a/plugins/kubernetes/src/error-detection/__fixtures__/hpa-maxed-out.json b/plugins/kubernetes-common/src/error-detection/__fixtures__/hpa-maxed-out.json similarity index 100% rename from plugins/kubernetes/src/error-detection/__fixtures__/hpa-maxed-out.json rename to plugins/kubernetes-common/src/error-detection/__fixtures__/hpa-maxed-out.json diff --git a/plugins/kubernetes/src/error-detection/__fixtures__/pod-crashing.json b/plugins/kubernetes-common/src/error-detection/__fixtures__/pod-crashing.json similarity index 100% rename from plugins/kubernetes/src/error-detection/__fixtures__/pod-crashing.json rename to plugins/kubernetes-common/src/error-detection/__fixtures__/pod-crashing.json diff --git a/plugins/kubernetes/src/error-detection/__fixtures__/pod-missing-cm.json b/plugins/kubernetes-common/src/error-detection/__fixtures__/pod-missing-cm.json similarity index 100% rename from plugins/kubernetes/src/error-detection/__fixtures__/pod-missing-cm.json rename to plugins/kubernetes-common/src/error-detection/__fixtures__/pod-missing-cm.json diff --git a/plugins/kubernetes/src/components/Pods/__fixtures__/pod.json b/plugins/kubernetes-common/src/error-detection/__fixtures__/pod.json similarity index 100% rename from plugins/kubernetes/src/components/Pods/__fixtures__/pod.json rename to plugins/kubernetes-common/src/error-detection/__fixtures__/pod.json diff --git a/plugins/kubernetes/src/error-detection/common.ts b/plugins/kubernetes-common/src/error-detection/common.ts similarity index 100% rename from plugins/kubernetes/src/error-detection/common.ts rename to plugins/kubernetes-common/src/error-detection/common.ts diff --git a/plugins/kubernetes/src/error-detection/deployments.ts b/plugins/kubernetes-common/src/error-detection/deployments.ts similarity index 100% rename from plugins/kubernetes/src/error-detection/deployments.ts rename to plugins/kubernetes-common/src/error-detection/deployments.ts diff --git a/plugins/kubernetes/src/error-detection/error-detection.test.ts b/plugins/kubernetes-common/src/error-detection/error-detection.test.ts similarity index 100% rename from plugins/kubernetes/src/error-detection/error-detection.test.ts rename to plugins/kubernetes-common/src/error-detection/error-detection.test.ts diff --git a/plugins/kubernetes/src/error-detection/error-detection.ts b/plugins/kubernetes-common/src/error-detection/error-detection.ts similarity index 97% rename from plugins/kubernetes/src/error-detection/error-detection.ts rename to plugins/kubernetes-common/src/error-detection/error-detection.ts index c33de18b80..a3a4d58d9e 100644 --- a/plugins/kubernetes/src/error-detection/error-detection.ts +++ b/plugins/kubernetes-common/src/error-detection/error-detection.ts @@ -16,7 +16,7 @@ import { DetectedError, DetectedErrorsByCluster } from './types'; import { ObjectsByEntityResponse } from '@backstage/plugin-kubernetes-common'; -import { groupResponses } from '../utils/response'; +import { groupResponses } from '../util'; import { detectErrorsInPods } from './pods'; import { detectErrorsInDeployments } from './deployments'; import { detectErrorsInHpa } from './hpas'; diff --git a/plugins/kubernetes/src/error-detection/hpas.ts b/plugins/kubernetes-common/src/error-detection/hpas.ts similarity index 100% rename from plugins/kubernetes/src/error-detection/hpas.ts rename to plugins/kubernetes-common/src/error-detection/hpas.ts diff --git a/plugins/kubernetes-common/src/error-detection/index.ts b/plugins/kubernetes-common/src/error-detection/index.ts new file mode 100644 index 0000000000..0b79b023c2 --- /dev/null +++ b/plugins/kubernetes-common/src/error-detection/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2020 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 './types'; +export { detectErrors } from './error-detection'; diff --git a/plugins/kubernetes/src/error-detection/pods.ts b/plugins/kubernetes-common/src/error-detection/pods.ts similarity index 100% rename from plugins/kubernetes/src/error-detection/pods.ts rename to plugins/kubernetes-common/src/error-detection/pods.ts diff --git a/plugins/kubernetes/src/error-detection/types.ts b/plugins/kubernetes-common/src/error-detection/types.ts similarity index 93% rename from plugins/kubernetes/src/error-detection/types.ts rename to plugins/kubernetes-common/src/error-detection/types.ts index 4148056171..bf918bbacb 100644 --- a/plugins/kubernetes/src/error-detection/types.ts +++ b/plugins/kubernetes-common/src/error-detection/types.ts @@ -54,29 +54,35 @@ export interface DetectedError { occurrenceCount: number; } +/** @public */ export type ProposedFix = LogSolution | DocsSolution | EventsSolution; -interface ProposedFixBase { +/** @public */ +export interface ProposedFixBase { errorType: string; rootCauseExplanation: string; actions: string[]; } +/** @public */ export interface LogSolution extends ProposedFixBase { type: 'logs'; container: string; } +/** @public */ export interface DocsSolution extends ProposedFixBase { type: 'docs'; docsLink: string; } +/** @public */ export interface EventsSolution extends ProposedFixBase { type: 'events'; podName: string; } +/** @public */ export interface ErrorMapper { detectErrors: (resource: T) => DetectedError[]; } diff --git a/plugins/kubernetes-common/src/index.ts b/plugins/kubernetes-common/src/index.ts index d5cf8dcf61..6704242383 100644 --- a/plugins/kubernetes-common/src/index.ts +++ b/plugins/kubernetes-common/src/index.ts @@ -26,3 +26,5 @@ export { kubernetesProxyPermission, kubernetesPermissions, } from './permissions'; +export * from './error-detection'; +export * from './util'; diff --git a/plugins/kubernetes-common/src/types.ts b/plugins/kubernetes-common/src/types.ts index feb213d520..9648293432 100644 --- a/plugins/kubernetes-common/src/types.ts +++ b/plugins/kubernetes-common/src/types.ts @@ -262,3 +262,22 @@ export interface ClientPodStatus { memory: ClientCurrentResourceUsage; containers: ClientContainerStatus[]; } + +/** @public */ +export interface DeploymentResources { + pods: V1Pod[]; + replicaSets: V1ReplicaSet[]; + deployments: V1Deployment[]; + horizontalPodAutoscalers: V1HorizontalPodAutoscaler[]; +} + +/** @public */ +export interface GroupedResponses extends DeploymentResources { + services: V1Service[]; + configMaps: V1ConfigMap[]; + ingresses: V1Ingress[]; + jobs: V1Job[]; + cronJobs: V1CronJob[]; + customResources: any[]; + statefulsets: V1StatefulSet[]; +} diff --git a/plugins/kubernetes/src/components/Cluster/index.ts b/plugins/kubernetes-common/src/util/index.ts similarity index 94% rename from plugins/kubernetes/src/components/Cluster/index.ts rename to plugins/kubernetes-common/src/util/index.ts index dc9df63d42..1cc287df08 100644 --- a/plugins/kubernetes/src/components/Cluster/index.ts +++ b/plugins/kubernetes-common/src/util/index.ts @@ -13,4 +13,5 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export { Cluster } from './Cluster'; + +export * from './response'; diff --git a/plugins/kubernetes/src/utils/response.ts b/plugins/kubernetes-common/src/util/response.ts similarity index 95% rename from plugins/kubernetes/src/utils/response.ts rename to plugins/kubernetes-common/src/util/response.ts index 894b881f22..a86d90f780 100644 --- a/plugins/kubernetes/src/utils/response.ts +++ b/plugins/kubernetes-common/src/util/response.ts @@ -15,12 +15,13 @@ */ import { FetchResponse } from '@backstage/plugin-kubernetes-common'; -import { GroupedResponses } from '../types/types'; +import { GroupedResponses } from '../types'; -// TODO this could probably be a lodash groupBy +/** @public */ export const groupResponses = ( fetchResponse: FetchResponse[], ): GroupedResponses => { + // TODO this could probably be a lodash groupBy return fetchResponse.reduce( (prev, next) => { switch (next.type) { diff --git a/plugins/kubernetes-react/.eslintrc.js b/plugins/kubernetes-react/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/kubernetes-react/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/kubernetes-react/README.md b/plugins/kubernetes-react/README.md new file mode 100644 index 0000000000..02963c2e0a --- /dev/null +++ b/plugins/kubernetes-react/README.md @@ -0,0 +1,5 @@ +# @backstage/plugin-kubernetes-react + +Welcome to the web library package for the kubernetes-react plugin! + +_This plugin was created through the Backstage CLI_ diff --git a/plugins/kubernetes-react/api-report.md b/plugins/kubernetes-react/api-report.md new file mode 100644 index 0000000000..e182524426 --- /dev/null +++ b/plugins/kubernetes-react/api-report.md @@ -0,0 +1,751 @@ +## API Report File for "@backstage/plugin-kubernetes-react" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { ApiRef } from '@backstage/core-plugin-api'; +import { AsyncState } from 'react-use/lib/useAsyncFn'; +import { ClientContainerStatus } from '@backstage/plugin-kubernetes-common'; +import { ClientPodStatus } from '@backstage/plugin-kubernetes-common'; +import { ClusterAttributes } from '@backstage/plugin-kubernetes-common'; +import { ClusterObjects } from '@backstage/plugin-kubernetes-common'; +import { CustomObjectsByEntityRequest } from '@backstage/plugin-kubernetes-common'; +import { CustomResourceMatcher } from '@backstage/plugin-kubernetes-common'; +import { DetectedError } from '@backstage/plugin-kubernetes-common'; +import { DetectedErrorsByCluster } from '@backstage/plugin-kubernetes-common'; +import { DiscoveryApi } from '@backstage/core-plugin-api'; +import { Entity } from '@backstage/catalog-model'; +import { Event as Event_2 } from 'kubernetes-models/v1'; +import { GroupedResponses } from '@backstage/plugin-kubernetes-common'; +import { IContainer } from 'kubernetes-models/v1'; +import { IContainerStatus } from 'kubernetes-models/v1'; +import { IdentityApi } from '@backstage/core-plugin-api'; +import { IIoK8sApimachineryPkgApisMetaV1ObjectMeta } from '@kubernetes-models/apimachinery/apis/meta/v1/ObjectMeta'; +import { IObjectMeta } from '@kubernetes-models/apimachinery/apis/meta/v1/ObjectMeta'; +import { KubernetesRequestBody } from '@backstage/plugin-kubernetes-common'; +import { OAuthApi } from '@backstage/core-plugin-api'; +import { ObjectsByEntityResponse } from '@backstage/plugin-kubernetes-common'; +import { OpenIdConnectApi } from '@backstage/core-plugin-api'; +import { Pod } from 'kubernetes-models/v1'; +import { Pod as Pod_2 } from 'kubernetes-models/v1/Pod'; +import { default as React_2 } from 'react'; +import * as React_3 from 'react'; +import { TypeMeta } from '@kubernetes-models/base'; +import { V1HorizontalPodAutoscaler } from '@kubernetes/client-node'; +import { V1Job } from '@kubernetes/client-node'; +import { V1ObjectMeta } from '@kubernetes/client-node'; +import { V1Pod } from '@kubernetes/client-node'; +import { WorkloadsByEntityRequest } from '@backstage/plugin-kubernetes-common'; + +// @public (undocumented) +export class AksKubernetesAuthProvider implements KubernetesAuthProvider { + constructor(microsoftAuthApi: OAuthApi); + // (undocumented) + decorateRequestBodyForAuth( + requestBody: KubernetesRequestBody, + ): Promise; + // (undocumented) + getCredentials(): Promise<{ + token?: string; + }>; +} + +// @public +export const Cluster: ({ + clusterObjects, + podsWithErrors, +}: ClusterProps) => React_2.JSX.Element; + +// @public (undocumented) +export const ClusterContext: React_2.Context; + +// @public +export type ClusterProps = { + clusterObjects: ClusterObjects; + podsWithErrors: Set; + children?: React_2.ReactNode; +}; + +// @public +export const ContainerCard: React_2.FC; + +// @public +export interface ContainerCardProps { + // (undocumented) + containerMetrics?: ClientContainerStatus; + // (undocumented) + containerSpec?: IContainer; + // (undocumented) + containerStatus: IContainerStatus; + // (undocumented) + podScope: PodScope; +} + +// @public +export interface ContainerScope extends PodScope { + // (undocumented) + containerName: string; +} + +// @public (undocumented) +export const CronJobsAccordions: ({}: CronJobsAccordionsProps) => React_2.JSX.Element; + +// @public (undocumented) +export type CronJobsAccordionsProps = { + children?: React_2.ReactNode; +}; + +// @public (undocumented) +export const CustomResources: ({}: CustomResourcesProps) => React_2.JSX.Element; + +// @public (undocumented) +export interface CustomResourcesProps { + // (undocumented) + children?: React_2.ReactNode; +} + +// @public +export const DetectedErrorsContext: React_2.Context; + +// @public +export const ErrorList: ({ + podAndErrors, +}: ErrorListProps) => React_2.JSX.Element; + +// @public +export interface ErrorListProps { + // (undocumented) + podAndErrors: PodAndErrors[]; +} + +// @public (undocumented) +export type ErrorMatcher = { + metadata?: IIoK8sApimachineryPkgApisMetaV1ObjectMeta; +} & TypeMeta; + +// @public (undocumented) +export const ErrorPanel: ({ + entityName, + errorMessage, + clustersWithErrors, +}: ErrorPanelProps) => React_2.JSX.Element; + +// @public (undocumented) +export type ErrorPanelProps = { + entityName: string; + errorMessage?: string; + clustersWithErrors?: ClusterObjects[]; + children?: React_2.ReactNode; +}; + +// @public (undocumented) +export const ErrorReporting: ({ + detectedErrors, +}: ErrorReportingProps) => React_3.JSX.Element; + +// @public (undocumented) +export type ErrorReportingProps = { + detectedErrors: DetectedErrorsByCluster; +}; + +// @public +export const Events: ({ + involvedObjectName, + namespace, + clusterName, + warningEventsOnly, +}: EventsProps) => React_2.JSX.Element; + +// @public +export const EventsContent: ({ + events, + warningEventsOnly, +}: EventsContentProps) => React_2.JSX.Element; + +// @public +export interface EventsContentProps { + // (undocumented) + events: Event_2[]; + // (undocumented) + warningEventsOnly?: boolean; +} + +// @public +export interface EventsOptions { + // (undocumented) + clusterName: string; + // (undocumented) + involvedObjectName: string; + // (undocumented) + namespace: string; +} + +// @public +export interface EventsProps { + // (undocumented) + clusterName: string; + // (undocumented) + involvedObjectName: string; + // (undocumented) + namespace: string; + // (undocumented) + warningEventsOnly?: boolean; +} + +// @public +export const FixDialog: React_2.FC; + +// @public +export interface FixDialogProps { + // (undocumented) + clusterName: string; + // (undocumented) + error: DetectedError; + // (undocumented) + open?: boolean; + // (undocumented) + pod: Pod_2; +} + +// @public (undocumented) +export class GoogleKubernetesAuthProvider implements KubernetesAuthProvider { + constructor(authProvider: OAuthApi); + // (undocumented) + authProvider: OAuthApi; + // (undocumented) + decorateRequestBodyForAuth( + requestBody: KubernetesRequestBody, + ): Promise; + // (undocumented) + getCredentials(): Promise<{ + token: string; + }>; +} + +// @public (undocumented) +export const GroupedResponsesContext: React_2.Context; + +// @public (undocumented) +export const HorizontalPodAutoscalerDrawer: (props: { + hpa: V1HorizontalPodAutoscaler; + expanded?: boolean; + children?: React_2.ReactNode; +}) => React_2.JSX.Element; + +// @public (undocumented) +export const IngressesAccordions: ({}: IngressesAccordionsProps) => React_2.JSX.Element; + +// @public (undocumented) +export type IngressesAccordionsProps = {}; + +// @public (undocumented) +export const JobsAccordions: ({ + jobs, +}: JobsAccordionsProps) => React_2.JSX.Element; + +// @public (undocumented) +export type JobsAccordionsProps = { + jobs: V1Job[]; + children?: React_2.ReactNode; +}; + +// @public (undocumented) +export interface KubernetesApi { + // (undocumented) + getClusters(): Promise< + { + name: string; + authProvider: string; + oidcTokenProvider?: string | undefined; + }[] + >; + // (undocumented) + getCustomObjectsByEntity( + request: CustomObjectsByEntityRequest, + ): Promise; + // (undocumented) + getObjectsByEntity( + requestBody: KubernetesRequestBody, + ): Promise; + // (undocumented) + getWorkloadsByEntity( + request: WorkloadsByEntityRequest, + ): Promise; + // (undocumented) + proxy(options: { + clusterName: string; + path: string; + init?: RequestInit; + }): Promise; +} + +// @public (undocumented) +export const kubernetesApiRef: ApiRef; + +// @public (undocumented) +export interface KubernetesAuthProvider { + // (undocumented) + decorateRequestBodyForAuth( + requestBody: KubernetesRequestBody, + ): Promise; + // (undocumented) + getCredentials(): Promise<{ + token?: string; + }>; +} + +// @public (undocumented) +export class KubernetesAuthProviders implements KubernetesAuthProvidersApi { + constructor(options: { + microsoftAuthApi: OAuthApi; + googleAuthApi: OAuthApi; + oidcProviders?: { + [key: string]: OpenIdConnectApi; + }; + }); + // (undocumented) + decorateRequestBodyForAuth( + authProvider: string, + requestBody: KubernetesRequestBody, + ): Promise; + // (undocumented) + getCredentials(authProvider: string): Promise<{ + token?: string; + }>; +} + +// @public (undocumented) +export interface KubernetesAuthProvidersApi { + // (undocumented) + decorateRequestBodyForAuth( + authProvider: string, + requestBody: KubernetesRequestBody, + ): Promise; + // (undocumented) + getCredentials(authProvider: string): Promise<{ + token?: string; + }>; +} + +// @public (undocumented) +export const kubernetesAuthProvidersApiRef: ApiRef; + +// @public (undocumented) +export class KubernetesBackendClient implements KubernetesApi { + constructor(options: { + discoveryApi: DiscoveryApi; + identityApi: IdentityApi; + kubernetesAuthProvidersApi: KubernetesAuthProvidersApi; + }); + // (undocumented) + getClusters(): Promise< + { + name: string; + authProvider: string; + }[] + >; + // (undocumented) + getCustomObjectsByEntity( + request: CustomObjectsByEntityRequest, + ): Promise; + // (undocumented) + getObjectsByEntity( + requestBody: KubernetesRequestBody, + ): Promise; + // (undocumented) + getWorkloadsByEntity( + request: WorkloadsByEntityRequest, + ): Promise; + // (undocumented) + proxy(options: { + clusterName: string; + path: string; + init?: RequestInit; + }): Promise; +} + +// @public +export const KubernetesDrawer: ({ + open, + label, + drawerContentsHeader, + kubernetesObject, + children, +}: KubernetesDrawerProps) => React_2.JSX.Element; + +// @public (undocumented) +export interface KubernetesDrawerable { + // (undocumented) + metadata?: V1ObjectMeta; +} + +// @public +export interface KubernetesDrawerProps { + // (undocumented) + children?: React_2.ReactNode; + // (undocumented) + drawerContentsHeader?: React_2.ReactNode; + // (undocumented) + kubernetesObject: KubernetesObject; + // (undocumented) + label: React_2.ReactNode; + // (undocumented) + open?: boolean; +} + +// @public +export interface KubernetesObject { + // (undocumented) + kind: string; + // (undocumented) + metadata?: IObjectMeta; +} + +// @public (undocumented) +export interface KubernetesObjects { + // (undocumented) + error?: string; + // (undocumented) + kubernetesObjects?: ObjectsByEntityResponse; + // (undocumented) + loading: boolean; +} + +// @public (undocumented) +export interface KubernetesProxyApi { + // (undocumented) + getEventsByInvolvedObjectName(request: { + clusterName: string; + involvedObjectName: string; + namespace: string; + }): Promise; + // (undocumented) + getPodLogs(request: { + podName: string; + namespace: string; + clusterName: string; + containerName: string; + previous?: boolean; + }): Promise<{ + text: string; + }>; +} + +// @public (undocumented) +export const kubernetesProxyApiRef: ApiRef; + +// @public +export class KubernetesProxyClient { + constructor(options: { kubernetesApi: KubernetesApi }); + // (undocumented) + getEventsByInvolvedObjectName({ + clusterName, + involvedObjectName, + namespace, + }: { + clusterName: string; + involvedObjectName: string; + namespace: string; + }): Promise; + // (undocumented) + getPodLogs({ + podName, + namespace, + clusterName, + containerName, + previous, + }: { + podName: string; + namespace: string; + clusterName: string; + containerName: string; + previous?: boolean; + }): Promise<{ + text: string; + }>; +} + +// @public (undocumented) +export const KubernetesStructuredMetadataTableDrawer: < + T extends KubernetesDrawerable, +>({ + object, + renderObject, + kind, + buttonVariant, + expanded, + children, +}: KubernetesStructuredMetadataTableDrawerProps) => React_2.JSX.Element; + +// @public (undocumented) +export interface KubernetesStructuredMetadataTableDrawerProps< + T extends KubernetesDrawerable, +> { + // (undocumented) + buttonVariant?: 'h5' | 'subtitle2'; + // (undocumented) + children?: React_2.ReactNode; + // (undocumented) + expanded?: boolean; + // (undocumented) + kind: string; + // (undocumented) + object: T; + // (undocumented) + renderObject: (obj: T) => object; +} + +// @public (undocumented) +export const LinkErrorPanel: ({ + cluster, + errorMessage, +}: LinkErrorPanelProps) => React_2.JSX.Element; + +// @public (undocumented) +export type LinkErrorPanelProps = { + cluster: ClusterAttributes; + errorMessage?: string; + children?: React_2.ReactNode; +}; + +// @public +export const ManifestYaml: ({ + object, +}: ManifestYamlProps) => React_2.JSX.Element; + +// @public +export interface ManifestYamlProps { + // (undocumented) + object: object; +} + +// @public (undocumented) +export class OidcKubernetesAuthProvider implements KubernetesAuthProvider { + constructor(providerName: string, authProvider: OpenIdConnectApi); + // (undocumented) + authProvider: OpenIdConnectApi; + // (undocumented) + decorateRequestBodyForAuth( + requestBody: KubernetesRequestBody, + ): Promise; + // (undocumented) + getCredentials(): Promise<{ + token: string; + }>; + // (undocumented) + providerName: string; +} + +// @public +export const PendingPodContent: ({ + pod, +}: PendingPodContentProps) => React_2.JSX.Element; + +// @public +export interface PendingPodContentProps { + // (undocumented) + pod: Pod; +} + +// @public +export interface PodAndErrors { + // (undocumented) + clusterName: string; + // (undocumented) + errors: DetectedError[]; + // (undocumented) + pod: Pod; +} + +// @public (undocumented) +export type PodColumns = 'READY' | 'RESOURCE'; + +// @public +export const PodDrawer: ({ + podAndErrors, + open, +}: PodDrawerProps) => React_2.JSX.Element; + +// @public +export interface PodDrawerProps { + // (undocumented) + open?: boolean; + // (undocumented) + podAndErrors: PodAndErrors; +} + +// @public +export const PodExecTerminal: ( + props: PodExecTerminalProps, +) => React_2.JSX.Element; + +// @public +export const PodExecTerminalDialog: ( + props: PodExecTerminalProps, +) => React_2.JSX.Element; + +// @public +export interface PodExecTerminalProps { + // (undocumented) + clusterName: string; + // (undocumented) + containerName: string; + // (undocumented) + podName: string; + // (undocumented) + podNamespace: string; +} + +// @public +export const PodLogs: React_2.FC; + +// @public +export const PodLogsDialog: ({ + containerScope, +}: PodLogsDialogProps) => React_2.JSX.Element; + +// @public +export interface PodLogsDialogProps { + // (undocumented) + containerScope: ContainerScope; +} + +// @public +export interface PodLogsOptions { + // (undocumented) + containerScope: ContainerScope; + // (undocumented) + previous?: boolean; +} + +// @public +export interface PodLogsProps { + // (undocumented) + containerScope: ContainerScope; + // (undocumented) + previous?: boolean; +} + +// @public +export const PodMetricsContext: React_2.Context>; + +// @public (undocumented) +export type PodMetricsMatcher = { + metadata?: IObjectMeta; +}; + +// @public (undocumented) +export const PodNamesWithErrorsContext: React_2.Context>; + +// @public (undocumented) +export const PodNamesWithMetricsContext: React_2.Context< + Map +>; + +// @public +export interface PodScope { + // (undocumented) + clusterName: string; + // (undocumented) + podName: string; + // (undocumented) + podNamespace: string; +} + +// @public (undocumented) +export const PodsTable: ({ + pods, + extraColumns, +}: PodsTablesProps) => React_2.JSX.Element; + +// @public (undocumented) +export type PodsTablesProps = { + pods: Pod_2 | V1Pod[]; + extraColumns?: PodColumns[]; + children?: React_2.ReactNode; +}; + +// @public (undocumented) +export const READY_COLUMNS: PodColumns; + +// @public (undocumented) +export const RESOURCE_COLUMNS: PodColumns; + +// @public +export const ResourceUtilization: ({ + compressed, + title, + usage, + total, + totalFormatted, +}: ResourceUtilizationProps) => React_2.JSX.Element; + +// @public +export interface ResourceUtilizationProps { + // (undocumented) + compressed?: boolean; + // (undocumented) + title: string; + // (undocumented) + total: number | string; + // (undocumented) + totalFormatted: string; + // (undocumented) + usage: number | string; +} + +// @public +export class ServerSideKubernetesAuthProvider + implements KubernetesAuthProvider +{ + // (undocumented) + decorateRequestBodyForAuth( + requestBody: KubernetesRequestBody, + ): Promise; + // (undocumented) + getCredentials(): Promise<{}>; +} + +// @public (undocumented) +export const ServicesAccordions: ({}: ServicesAccordionsProps) => React_2.JSX.Element; + +// @public (undocumented) +export type ServicesAccordionsProps = {}; + +// @public +export const useCustomResources: ( + entity: Entity, + customResourceMatchers: CustomResourceMatcher[], + intervalMs?: number, +) => KubernetesObjects; + +// @public +export const useEvents: ({ + involvedObjectName, + namespace, + clusterName, +}: EventsOptions) => AsyncState; + +// @public (undocumented) +export const useKubernetesObjects: ( + entity: Entity, + intervalMs?: number, +) => KubernetesObjects; + +// @public +export const useMatchingErrors: (matcher: ErrorMatcher) => DetectedError[]; + +// @public +export const usePodLogs: ({ + containerScope, + previous, +}: PodLogsOptions) => AsyncState<{ + text: string; +}>; + +// @public +export const usePodMetrics: ( + clusterName: string, + matcher: PodMetricsMatcher, +) => ClientPodStatus | undefined; +``` diff --git a/plugins/kubernetes-react/catalog-info.yaml b/plugins/kubernetes-react/catalog-info.yaml new file mode 100644 index 0000000000..a2fb40d32c --- /dev/null +++ b/plugins/kubernetes-react/catalog-info.yaml @@ -0,0 +1,11 @@ +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: backstage-plugin-kubernetes-react + title: '@backstage/plugin-kubernetes-react' + description: >- + Shared frontend utilities for Kubernetes plugins +spec: + lifecycle: experimental + type: backstage-web-library + owner: kubernetes-maintainers diff --git a/plugins/kubernetes-react/package.json b/plugins/kubernetes-react/package.json new file mode 100644 index 0000000000..5c95b29870 --- /dev/null +++ b/plugins/kubernetes-react/package.json @@ -0,0 +1,66 @@ +{ + "name": "@backstage/plugin-kubernetes-react", + "description": "Web library for the kubernetes-react plugin", + "version": "0.0.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": "web-library" + }, + "sideEffects": false, + "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/catalog-model": "workspace:^", + "@backstage/core-components": "workspace:^", + "@backstage/core-plugin-api": "workspace:^", + "@backstage/errors": "workspace:^", + "@backstage/plugin-kubernetes-common": "workspace:^", + "@backstage/types": "workspace:^", + "@kubernetes-models/apimachinery": "^1.1.0", + "@kubernetes-models/base": "^4.0.1", + "@kubernetes/client-node": "^0.19.0", + "@material-ui/core": "^4.9.13", + "@material-ui/icons": "^4.11.3", + "@material-ui/lab": "^4.0.0-alpha.61", + "@types/react": "^16.13.1 || ^17.0.0", + "cronstrue": "^2.32.0", + "js-yaml": "^4.1.0", + "kubernetes-models": "^4.3.1", + "lodash": "^4.17.21", + "luxon": "^3.0.0", + "react-use": "^17.4.0", + "xterm": "^5.3.0", + "xterm-addon-attach": "^0.9.0", + "xterm-addon-fit": "^0.8.0" + }, + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0" + }, + "devDependencies": { + "@backstage/cli": "workspace:^", + "@backstage/core-app-api": "workspace:^", + "@backstage/test-utils": "workspace:^", + "@testing-library/jest-dom": "^5.10.1", + "@testing-library/react": "^12.1.3", + "@testing-library/react-hooks": "^8.0.1", + "jest-websocket-mock": "^2.5.0", + "msw": "^1.3.1" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/kubernetes-react/src/__fixtures__/1-cronjobs.json b/plugins/kubernetes-react/src/__fixtures__/1-cronjobs.json new file mode 100644 index 0000000000..1edc43710d --- /dev/null +++ b/plugins/kubernetes-react/src/__fixtures__/1-cronjobs.json @@ -0,0 +1,446 @@ +{ + "cronJobs": [ + { + "metadata": { + "name": "dice-roller-cronjob", + "namespace": "default", + "uid": "9ea073bc-7a4b-4b99-8321-0305bce85568", + "resourceVersion": "1362732552", + "creationTimestamp": "2021-07-16T22:39:58Z", + "labels": { + "backstage.io/kubernetes-id": "dice-roller" + }, + "annotations": {} + }, + "spec": { + "schedule": "30 5 * * *", + "startingDeadlineSeconds": 1800, + "concurrencyPolicy": "Forbid", + "suspend": false, + "jobTemplate": { + "metadata": { "creationTimestamp": null }, + "spec": { + "backoffLimit": 2, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "backstage.io/kubernetes-id": "dice-roller" + }, + "annotations": {} + }, + "spec": { + "containers": [ + { + "name": "busybox", + "image": "busybox", + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "imagePullPolicy": "IfNotPresent", + "command": ["/bin/sh", "-c", "date; echo Rolling a die!"] + } + ], + "restartPolicy": "Never", + "terminationGracePeriodSeconds": 30, + "dnsPolicy": "ClusterFirst", + "securityContext": {}, + "schedulerName": "default-scheduler" + } + } + } + }, + "successfulJobsHistoryLimit": 2, + "failedJobsHistoryLimit": 2 + }, + "status": { + "active": [ + { + "kind": "Job", + "namespace": "default", + "name": "dice-roller-cronjob-1637028600", + "uid": "32be1b89-5b53-45b2-aa84-277e75214f61", + "apiVersion": "batch/v1", + "resourceVersion": "1361174163" + } + ], + "lastScheduleTime": "2021-11-16T02:10:00Z" + } + } + ], + "jobs": [ + { + "metadata": { + "name": "dice-roller-cronjob-1637025000", + "namespace": "default", + "uid": "69d5d242-a9a4-47b8-b9c7-c536ae8f151a", + "resourceVersion": "1361029181", + "creationTimestamp": "2021-11-16T01:10:24Z", + "labels": { + "backstage.io/kubernetes-id": "dice-roller" + }, + "ownerReferences": [ + { + "apiVersion": "batch/v1", + "kind": "CronJob", + "name": "dice-roller-cronjob", + "uid": "9ea073bc-7a4b-4b99-8321-0305bce85568", + "controller": true, + "blockOwnerDeletion": true + } + ] + }, + "spec": { + "parallelism": 1, + "completions": 1, + "backoffLimit": 2, + "selector": { + "matchLabels": { + "controller-uid": "69d5d242-a9a4-47b8-b9c7-c536ae8f151a" + } + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "backstage.io/kubernetes-id": "dice-roller", + "controller-uid": "69d5d242-a9a4-47b8-b9c7-c536ae8f151a", + "job-name": "dice-roller-cronjob-1637025000" + }, + "annotations": {} + }, + "spec": { + "containers": [ + { + "command": ["/bin/sh", "-c", "date; echo Rolling a die!"], + "image": "busybox", + "imagePullPolicy": "IfNotPresent", + "name": "busybox", + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + } + ], + "restartPolicy": "Never", + "terminationGracePeriodSeconds": 30, + "dnsPolicy": "ClusterFirst", + "securityContext": {}, + "schedulerName": "default-scheduler" + } + } + }, + "status": { + "conditions": [ + { + "type": "Complete", + "status": "True", + "lastProbeTime": "2021-11-16T01:11:31Z", + "lastTransitionTime": "2021-11-16T01:11:31Z" + } + ], + "startTime": "2021-11-16T01:10:24Z", + "completionTime": "2021-11-16T01:11:31Z", + "succeeded": 1 + } + }, + { + "metadata": { + "name": "dice-roller-cronjob-1637028600", + "namespace": "default", + "uid": "32be1b89-5b53-45b2-aa84-277e75214f61", + "resourceVersion": "1361174166", + "creationTimestamp": "2021-11-16T02:10:22Z", + "labels": { + "backstage.io/kubernetes-id": "dice-roller" + }, + "ownerReferences": [ + { + "apiVersion": "batch/v1", + "kind": "CronJob", + "name": "dice-roller-cronjob", + "uid": "9ea073bc-7a4b-4b99-8321-0305bce85568", + "controller": true, + "blockOwnerDeletion": true + } + ] + }, + "spec": { + "parallelism": 1, + "completions": 1, + "backoffLimit": 2, + "selector": { + "matchLabels": { + "controller-uid": "32be1b89-5b53-45b2-aa84-277e75214f61" + } + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "backstage.io/kubernetes-id": "dice-roller", + "controller-uid": "32be1b89-5b53-45b2-aa84-277e75214f61", + "job-name": "dice-roller-cronjob-1637028600" + }, + "annotations": {} + }, + "spec": { + "containers": [ + { + "command": ["/bin/sh", "-c", "date; echo Rolling a die!"], + "image": "busybox", + "imagePullPolicy": "IfNotPresent", + "name": "busybox", + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + } + ], + "restartPolicy": "Never", + "terminationGracePeriodSeconds": 30, + "dnsPolicy": "ClusterFirst", + "securityContext": {}, + "schedulerName": "default-scheduler" + } + } + }, + "status": { "startTime": "2021-11-16T02:10:22Z", "active": 1 } + } + ], + "pods": [ + { + "metadata": { + "name": "dice-roller-cronjob-1637025000-gstc4", + "generateName": "dice-roller-cronjob-1637025000-", + "namespace": "default", + "uid": "3b0f2b65-5ae2-441a-beda-bdc92bcafaf0", + "resourceVersion": "1361029179", + "creationTimestamp": "2021-11-16T01:10:24Z", + "labels": { + "backstage.io/kubernetes-id": "dice-roller", + "controller-uid": "69d5d242-a9a4-47b8-b9c7-c536ae8f151a", + "job-name": "dice-roller-cronjob-1637025000" + }, + "annotations": {}, + "ownerReferences": [ + { + "apiVersion": "batch/v1", + "kind": "Job", + "name": "dice-roller-cronjob-1637025000", + "uid": "69d5d242-a9a4-47b8-b9c7-c536ae8f151a", + "controller": true, + "blockOwnerDeletion": true + } + ] + }, + "spec": { + "volumes": [], + "containers": [ + { + "command": ["/bin/sh", "-c", "date; echo Rolling a die!"], + "image": "busybox", + "imagePullPolicy": "IfNotPresent", + "name": "busybox", + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + } + ], + "restartPolicy": "Never", + "terminationGracePeriodSeconds": 30, + "dnsPolicy": "ClusterFirst", + "serviceAccountName": "default", + "serviceAccount": "default", + "nodeName": "minikube", + "securityContext": {}, + "schedulerName": "default-scheduler", + "tolerations": [ + { + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "effect": "NoExecute", + "tolerationSeconds": 300 + }, + { + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "effect": "NoExecute", + "tolerationSeconds": 300 + } + ], + "priority": 0, + "enableServiceLinks": true + }, + "status": { + "phase": "Succeeded", + "conditions": [ + { + "type": "Initialized", + "status": "True", + "lastProbeTime": null, + "lastTransitionTime": "2021-11-16T01:10:27Z", + "reason": "PodCompleted" + }, + { + "type": "Ready", + "status": "False", + "lastProbeTime": null, + "lastTransitionTime": "2021-11-16T01:11:31Z", + "reason": "PodCompleted" + }, + { + "type": "ContainersReady", + "status": "False", + "lastProbeTime": null, + "lastTransitionTime": "2021-11-16T01:11:31Z", + "reason": "PodCompleted" + }, + { + "type": "PodScheduled", + "status": "True", + "lastProbeTime": null, + "lastTransitionTime": "2021-11-16T01:10:24Z" + } + ], + "hostIP": "192.168.49.2", + "podIP": "172.17.0.25", + "podIPs": [{ "ip": "172.17.0.25" }], + "startTime": "2021-11-16T01:10:24Z", + "containerStatuses": [ + { + "name": "busybox", + "state": { + "terminated": { + "exitCode": 0, + "reason": "Completed", + "startedAt": "2021-11-16T01:10:31Z", + "finishedAt": "2021-11-16T01:11:30Z", + "containerID": "docker://1062343e1bb3625e36717bc15617c1bbca976366c3c9dd87035c71f33d015615" + } + }, + "lastState": {}, + "ready": false, + "restartCount": 0, + "image": "busybox:latest/node", + "imageID": "docker-pullable://busybox@sha256:e7157b6d7ebbe2cce5eaa8cfe8aa4fa82d173999b9f90a9ec42e57323546c353", + "containerID": "docker://1062343e1bb3625e36717bc15617c1bbca976366c3c9dd87035c71f33d015615", + "started": false + } + ], + "qosClass": "Burstable" + } + }, + { + "metadata": { + "name": "dice-roller-cronjob-1637028600-p4mlc", + "generateName": "dice-roller-cronjob-1637028600-", + "namespace": "default", + "uid": "acddd5d2-ac7f-473b-a9d8-17a89f99ac39", + "resourceVersion": "1361174579", + "creationTimestamp": "2021-11-16T02:10:22Z", + "labels": { + "backstage.io/kubernetes-id": "dice-roller", + "controller-uid": "32be1b89-5b53-45b2-aa84-277e75214f61", + "job-name": "dice-roller-cronjob-1637028600" + }, + "annotations": {}, + "ownerReferences": [ + { + "apiVersion": "batch/v1", + "kind": "Job", + "name": "dice-roller-cronjob-1637028600", + "uid": "32be1b89-5b53-45b2-aa84-277e75214f61", + "controller": true, + "blockOwnerDeletion": true + } + ] + }, + "spec": { + "volumes": [], + "containers": [ + { + "command": ["/bin/sh", "-c", "date; echo Rolling a die!"], + "image": "busybox", + "imagePullPolicy": "IfNotPresent", + "name": "busybox", + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + } + ], + "restartPolicy": "Never", + "terminationGracePeriodSeconds": 30, + "dnsPolicy": "ClusterFirst", + "serviceAccountName": "default", + "serviceAccount": "default", + "nodeName": "minikube", + "securityContext": {}, + "schedulerName": "default-scheduler", + "tolerations": [ + { + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "effect": "NoExecute", + "tolerationSeconds": 300 + }, + { + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "effect": "NoExecute", + "tolerationSeconds": 300 + } + ], + "priority": 0, + "enableServiceLinks": true + }, + "status": { + "phase": "Running", + "conditions": [ + { + "type": "Initialized", + "status": "True", + "lastProbeTime": null, + "lastTransitionTime": "2021-11-16T02:10:25Z" + }, + { + "type": "Ready", + "status": "True", + "lastProbeTime": null, + "lastTransitionTime": "2021-11-16T02:10:35Z" + }, + { + "type": "ContainersReady", + "status": "True", + "lastProbeTime": null, + "lastTransitionTime": "2021-11-16T02:10:35Z" + }, + { + "type": "PodScheduled", + "status": "True", + "lastProbeTime": null, + "lastTransitionTime": "2021-11-16T02:10:22Z" + } + ], + "hostIP": "192.168.49.2", + "podIP": "172.17.0.25", + "podIPs": [{ "ip": "172.17.0.25" }], + "startTime": "2021-11-16T02:10:22Z", + "containerStatuses": [ + { + "name": "busybox", + "state": { + "running": { "startedAt": "2021-11-16T02:10:31Z" } + }, + "lastState": {}, + "ready": true, + "restartCount": 0, + "image": "busybox:latest", + "imageID": "docker-pullable://busybox@sha256:e7157b6d7ebbe2cce5eaa8cfe8aa4fa82d173999b9f90a9ec42e57323546c353", + "containerID": "docker://1062343e1bb3625e36717bc15617c1bbca976366c3c9dd87035c71f33d015615", + "started": true + } + ], + "qosClass": "Burstable" + } + } + ] +} diff --git a/plugins/kubernetes-react/src/__fixtures__/1-deployments.json b/plugins/kubernetes-react/src/__fixtures__/1-deployments.json new file mode 100644 index 0000000000..5ad847dc49 --- /dev/null +++ b/plugins/kubernetes-react/src/__fixtures__/1-deployments.json @@ -0,0 +1,2911 @@ +{ + "pods": [ + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.11\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:55.000Z" + } + ], + "name": "dice-roller-6c8646bfd-2m5hv", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593216", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-2m5hv", + "uid": "aadb71c0-36fa-43e3-b38a-162f134d4359" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://aa4489297c34c48bb33c18474a8d2b33854a82ed42155680b259f635f556ce70", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.11", + "podIPs": [ + { + "ip": "172.17.0.11" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:50.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.7\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:55.000Z" + } + ], + "name": "dice-roller-6c8646bfd-4v6s8", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593221", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-4v6s8", + "uid": "32e56490-6f20-4757-991f-a0c7fb407358" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://d91cc76c41249b8d3dfcf538d180b471b2a7966aae0d17a818307c8a9b4af897", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.7", + "podIPs": [ + { + "ip": "172.17.0.7" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:50.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-24T11:39:26.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-24T11:39:26.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.6\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-24T11:39:27.000Z" + } + ], + "name": "dice-roller-6c8646bfd-b9zt5", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "503886", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-b9zt5", + "uid": "8b6601b6-469e-4e89-8fd0-abb2f1a567e4" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:26.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:27.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:27.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:26.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://c50e0d0fa96f09a2ed5df7dd5a7f7de88e6b7c7addb8f002f299d6afc52d82ce", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-24T11:39:27.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.6", + "podIPs": [ + { + "ip": "172.17.0.6" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-24T11:39:26.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.13\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:55.000Z" + } + ], + "name": "dice-roller-6c8646bfd-cfxqc", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593211", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-cfxqc", + "uid": "e87e1776-0ca7-41fb-aeea-e1f648387545" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:51.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://c1641d986aae424429b7c2c1117baeb17d3794f73206bd57292cdf8264f929b2", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.13", + "podIPs": [ + { + "ip": "172.17.0.13" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:51.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.15\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:54.000Z" + } + ], + "name": "dice-roller-6c8646bfd-dtv5z", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593190", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-dtv5z", + "uid": "1638a41b-e47e-4c17-a1f7-7b447df248b6" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:51.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:53.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:53.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://e62c32db58dbfe0a74b2d2cba0e0a97b7f222693c68e930037ac8738c4758ca3", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.15", + "podIPs": [ + { + "ip": "172.17.0.15" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:51.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.12\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:53.000Z" + } + ], + "name": "dice-roller-6c8646bfd-hhts2", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593186", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-hhts2", + "uid": "ea0b147a-c56a-46e6-9445-7a0b1b0ed3c0" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:53.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:53.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://bcdbc153630f90556d57ff0d62f04d847ca63a5f0a7e5d9230683623d33d4b8d", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.12", + "podIPs": [ + { + "ip": "172.17.0.12" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:50.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.14\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:55.000Z" + } + ], + "name": "dice-roller-6c8646bfd-j68lm", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593226", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-j68lm", + "uid": "b230ff1d-7a13-479b-9c7b-77c26bd79f62" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://30fa8a3429f86ab8e9a4cec472b79d74266609082703f48950f4aae021e9d6a2", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.14", + "podIPs": [ + { + "ip": "172.17.0.14" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:50.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.9\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:53.000Z" + } + ], + "name": "dice-roller-6c8646bfd-m6f9w", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593181", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-m6f9w", + "uid": "9b0079f6-ff29-4619-bf6e-71cc10199ac5" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:53.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:53.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://f78767ee90eedffe46ff64bfe76d7f69426800dd89f3df012daf0baf3a9c5bdd", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.9", + "podIPs": [ + { + "ip": "172.17.0.9" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:50.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-24T11:39:27.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-24T11:39:27.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.4\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-24T11:39:28.000Z" + } + ], + "name": "dice-roller-6c8646bfd-nv9pk", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "503918", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-nv9pk", + "uid": "acf7f77f-78c6-4d4b-bc73-637211770ffc" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:27.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:28.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:28.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:27.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://63dec9b32942c4b09ae43d09d6978261f674a3ee623823b8f1d20da8044c12ac", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-24T11:39:28.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.4", + "podIPs": [ + { + "ip": "172.17.0.4" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-24T11:39:27.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.10\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:55.000Z" + } + ], + "name": "dice-roller-6c8646bfd-pjhfj", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593205", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-pjhfj", + "uid": "78775c3a-7af2-4ebe-a676-bc2e5dfa2bcc" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://cbb83dda250db74285dcbe0b81bd0896acf402bac9710af090311f7360f824aa", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.10", + "podIPs": [ + { + "ip": "172.17.0.10" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:50.000Z" + } + } + ], + "replicaSets": [ + { + "metadata": { + "annotations": { + "deployment.kubernetes.io/desired-replicas": "10", + "deployment.kubernetes.io/max-replicas": "13", + "deployment.kubernetes.io/revision": "2" + }, + "creationTimestamp": "2020-09-24T11:39:26.000Z", + "generation": 3, + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "apps/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:deployment.kubernetes.io/desired-replicas": {}, + "f:deployment.kubernetes.io/max-replicas": {}, + "f:deployment.kubernetes.io/revision": {} + }, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"7551e949-42d1-4061-83c5-9da107186e47\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:replicas": {}, + "f:selector": { + "f:matchLabels": { + ".": {}, + "f:app": {}, + "f:pod-template-hash": {} + } + }, + "f:template": { + "f:metadata": { + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + } + }, + "f:status": { + "f:availableReplicas": {}, + "f:fullyLabeledReplicas": {}, + "f:observedGeneration": {}, + "f:readyReplicas": {}, + "f:replicas": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:55.000Z" + } + ], + "name": "dice-roller-6c8646bfd", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "Deployment", + "name": "dice-roller", + "uid": "7551e949-42d1-4061-83c5-9da107186e47" + } + ], + "resourceVersion": "593228", + "selfLink": "/apis/apps/v1/namespaces/default/replicasets/dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + }, + "spec": { + "replicas": 10, + "selector": { + "matchLabels": { + "app": "dice-roller", + "pod-template-hash": "6c8646bfd" + } + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + } + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + } + ], + "dnsPolicy": "ClusterFirst", + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "terminationGracePeriodSeconds": 30 + } + } + }, + "status": { + "availableReplicas": 10, + "fullyLabeledReplicas": 10, + "observedGeneration": 3, + "readyReplicas": 10, + "replicas": 10 + } + } + ], + "deployments": [ + { + "metadata": { + "annotations": { + "deployment.kubernetes.io/revision": "2", + "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"apps/v1\",\"kind\":\"Deployment\",\"metadata\":{\"annotations\":{},\"labels\":{\"backstage.io/kubernetes-id\":\"dice-roller\"},\"name\":\"dice-roller\",\"namespace\":\"default\"},\"spec\":{\"replicas\":10,\"selector\":{\"matchLabels\":{\"app\":\"dice-roller\"}},\"template\":{\"metadata\":{\"labels\":{\"app\":\"dice-roller\",\"backstage.io/kubernetes-id\":\"dice-roller\"}},\"spec\":{\"containers\":[{\"image\":\"nginx:1.14.2\",\"name\":\"nginx\",\"ports\":[{\"containerPort\":80}]}]}}}}\n" + }, + "creationTimestamp": "2020-09-23T12:00:55.000Z", + "generation": 3, + "labels": { + "backstage.io/kubernetes-id": "dice-roller" + }, + "managedFields": [ + { + "apiVersion": "apps/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:kubectl.kubernetes.io/last-applied-configuration": {} + }, + "f:labels": { + ".": {}, + "f:backstage.io/kubernetes-id": {} + } + }, + "f:spec": { + "f:progressDeadlineSeconds": {}, + "f:replicas": {}, + "f:revisionHistoryLimit": {}, + "f:selector": { + "f:matchLabels": { + ".": {}, + "f:app": {} + } + }, + "f:strategy": { + "f:rollingUpdate": { + ".": {}, + "f:maxSurge": {}, + "f:maxUnavailable": {} + }, + "f:type": {} + }, + "f:template": { + "f:metadata": { + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {} + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + } + } + }, + "manager": "kubectl", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "apps/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + "f:deployment.kubernetes.io/revision": {} + } + }, + "f:status": { + "f:availableReplicas": {}, + "f:conditions": { + ".": {}, + "k:{\"type\":\"Available\"}": { + ".": {}, + "f:lastTransitionTime": {}, + "f:lastUpdateTime": {}, + "f:message": {}, + "f:reason": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Progressing\"}": { + ".": {}, + "f:lastTransitionTime": {}, + "f:lastUpdateTime": {}, + "f:message": {}, + "f:reason": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:observedGeneration": {}, + "f:readyReplicas": {}, + "f:replicas": {}, + "f:updatedReplicas": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:55.000Z" + } + ], + "name": "dice-roller", + "namespace": "default", + "resourceVersion": "593230", + "selfLink": "/apis/apps/v1/namespaces/default/deployments/dice-roller", + "uid": "7551e949-42d1-4061-83c5-9da107186e47" + }, + "spec": { + "progressDeadlineSeconds": 600, + "replicas": 10, + "revisionHistoryLimit": 10, + "selector": { + "matchLabels": { + "app": "dice-roller" + } + }, + "strategy": { + "rollingUpdate": { + "maxSurge": "25%", + "maxUnavailable": "25%" + }, + "type": "RollingUpdate" + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller" + } + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + } + ], + "dnsPolicy": "ClusterFirst", + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "terminationGracePeriodSeconds": 30 + } + } + }, + "status": { + "availableReplicas": 10, + "conditions": [ + { + "lastTransitionTime": "2020-09-23T12:00:55.000Z", + "lastUpdateTime": "2020-09-24T11:39:28.000Z", + "message": "ReplicaSet \"dice-roller-6c8646bfd\" has successfully progressed.", + "reason": "NewReplicaSetAvailable", + "status": "True", + "type": "Progressing" + }, + { + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "lastUpdateTime": "2020-09-25T09:58:55.000Z", + "message": "Deployment has minimum availability.", + "reason": "MinimumReplicasAvailable", + "status": "True", + "type": "Available" + } + ], + "observedGeneration": 3, + "readyReplicas": 10, + "replicas": 10, + "updatedReplicas": 10 + } + } + ], + "horizontalPodAutoscalers": [ + { + "apiVersion": "autoscaling/v1", + "kind": "HorizontalPodAutoscaler", + "metadata": { + "annotations": { + "autoscaling.alpha.kubernetes.io/conditions": "[{\"type\":\"AbleToScale\",\"status\":\"True\",\"lastTransitionTime\":\"2021-01-05T10:26:04Z\",\"reason\":\"SucceededGetScale\",\"message\":\"the HPA controller was able to get the target's current scale\"},{\"type\":\"ScalingActive\",\"status\":\"False\",\"lastTransitionTime\":\"2021-01-05T10:26:04Z\",\"reason\":\"FailedGetResourceMetric\",\"message\":\"the HPA was unable to compute the replica count: unable to get metrics for resource cpu: no metrics returned from resource metrics API\"}]", + "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"autoscaling/v1\",\"kind\":\"HorizontalPodAutoscaler\",\"metadata\":{\"annotations\":{},\"labels\":{\"backstage.io/kubernetes-id\":\"dice-roller\"},\"name\":\"dice-roller\",\"namespace\":\"default\"},\"spec\":{\"maxReplicas\":15,\"minReplicas\":10,\"scaleTargetRef\":{\"apiVersion\":\"apps/v1\",\"kind\":\"Deployment\",\"name\":\"dice-roller\"},\"targetCPUUtilizationPercentage\":50}}\n" + }, + "creationTimestamp": "2021-01-05T10:25:48Z", + "labels": { + "backstage.io/kubernetes-id": "dice-roller" + }, + "managedFields": [ + { + "apiVersion": "autoscaling/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:kubectl.kubernetes.io/last-applied-configuration": {} + }, + "f:labels": { + ".": {}, + "f:backstage.io/kubernetes-id": {} + } + }, + "f:spec": { + "f:maxReplicas": {}, + "f:minReplicas": {}, + "f:scaleTargetRef": { + "f:apiVersion": {}, + "f:kind": {}, + "f:name": {} + }, + "f:targetCPUUtilizationPercentage": {} + } + }, + "manager": "kubectl-client-side-apply", + "operation": "Update", + "time": "2021-01-05T10:25:48Z" + }, + { + "apiVersion": "autoscaling/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + "f:autoscaling.alpha.kubernetes.io/conditions": {} + } + }, + "f:status": { + "f:currentReplicas": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2021-01-05T10:26:04Z" + } + ], + "name": "dice-roller", + "namespace": "default", + "resourceVersion": "598", + "selfLink": "/apis/autoscaling/v1/namespaces/default/horizontalpodautoscalers/dice-roller", + "uid": "dd7c5329-567c-43c2-b159-756808d90a8e" + }, + "spec": { + "maxReplicas": 15, + "minReplicas": 10, + "scaleTargetRef": { + "apiVersion": "apps/v1", + "kind": "Deployment", + "name": "dice-roller" + }, + "targetCPUUtilizationPercentage": 50 + }, + "status": { + "currentReplicas": 10, + "desiredReplicas": 0, + "currentCPUUtilizationPercentage": 30 + } + } + ] +} diff --git a/plugins/kubernetes-react/src/__fixtures__/1-statefulsets.json b/plugins/kubernetes-react/src/__fixtures__/1-statefulsets.json new file mode 100644 index 0000000000..6c04774ff1 --- /dev/null +++ b/plugins/kubernetes-react/src/__fixtures__/1-statefulsets.json @@ -0,0 +1,2912 @@ +{ + "pods": [ + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.11\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:55.000Z" + } + ], + "name": "dice-roller-6c8646bfd-2m5hv", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593216", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-2m5hv", + "uid": "aadb71c0-36fa-43e3-b38a-162f134d4359" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://aa4489297c34c48bb33c18474a8d2b33854a82ed42155680b259f635f556ce70", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.11", + "podIPs": [ + { + "ip": "172.17.0.11" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:50.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.7\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:55.000Z" + } + ], + "name": "dice-roller-6c8646bfd-4v6s8", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593221", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-4v6s8", + "uid": "32e56490-6f20-4757-991f-a0c7fb407358" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://d91cc76c41249b8d3dfcf538d180b471b2a7966aae0d17a818307c8a9b4af897", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.7", + "podIPs": [ + { + "ip": "172.17.0.7" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:50.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-24T11:39:26.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-24T11:39:26.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.6\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-24T11:39:27.000Z" + } + ], + "name": "dice-roller-6c8646bfd-b9zt5", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "503886", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-b9zt5", + "uid": "8b6601b6-469e-4e89-8fd0-abb2f1a567e4" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:26.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:27.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:27.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:26.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://c50e0d0fa96f09a2ed5df7dd5a7f7de88e6b7c7addb8f002f299d6afc52d82ce", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-24T11:39:27.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.6", + "podIPs": [ + { + "ip": "172.17.0.6" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-24T11:39:26.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.13\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:55.000Z" + } + ], + "name": "dice-roller-6c8646bfd-cfxqc", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593211", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-cfxqc", + "uid": "e87e1776-0ca7-41fb-aeea-e1f648387545" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:51.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://c1641d986aae424429b7c2c1117baeb17d3794f73206bd57292cdf8264f929b2", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.13", + "podIPs": [ + { + "ip": "172.17.0.13" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:51.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.15\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:54.000Z" + } + ], + "name": "dice-roller-6c8646bfd-dtv5z", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593190", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-dtv5z", + "uid": "1638a41b-e47e-4c17-a1f7-7b447df248b6" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:51.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:53.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:53.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://e62c32db58dbfe0a74b2d2cba0e0a97b7f222693c68e930037ac8738c4758ca3", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.15", + "podIPs": [ + { + "ip": "172.17.0.15" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:51.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.12\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:53.000Z" + } + ], + "name": "dice-roller-6c8646bfd-hhts2", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593186", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-hhts2", + "uid": "ea0b147a-c56a-46e6-9445-7a0b1b0ed3c0" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:53.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:53.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://bcdbc153630f90556d57ff0d62f04d847ca63a5f0a7e5d9230683623d33d4b8d", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.12", + "podIPs": [ + { + "ip": "172.17.0.12" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:50.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.14\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:55.000Z" + } + ], + "name": "dice-roller-6c8646bfd-j68lm", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593226", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-j68lm", + "uid": "b230ff1d-7a13-479b-9c7b-77c26bd79f62" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://30fa8a3429f86ab8e9a4cec472b79d74266609082703f48950f4aae021e9d6a2", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.14", + "podIPs": [ + { + "ip": "172.17.0.14" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:50.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.9\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:53.000Z" + } + ], + "name": "dice-roller-6c8646bfd-m6f9w", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593181", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-m6f9w", + "uid": "9b0079f6-ff29-4619-bf6e-71cc10199ac5" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:53.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:53.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://f78767ee90eedffe46ff64bfe76d7f69426800dd89f3df012daf0baf3a9c5bdd", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.9", + "podIPs": [ + { + "ip": "172.17.0.9" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:50.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-24T11:39:27.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-24T11:39:27.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.4\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-24T11:39:28.000Z" + } + ], + "name": "dice-roller-6c8646bfd-nv9pk", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "503918", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-nv9pk", + "uid": "acf7f77f-78c6-4d4b-bc73-637211770ffc" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:27.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:28.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:28.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:27.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://63dec9b32942c4b09ae43d09d6978261f674a3ee623823b8f1d20da8044c12ac", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-24T11:39:28.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.4", + "podIPs": [ + { + "ip": "172.17.0.4" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-24T11:39:27.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.10\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:55.000Z" + } + ], + "name": "dice-roller-6c8646bfd-pjhfj", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593205", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-pjhfj", + "uid": "78775c3a-7af2-4ebe-a676-bc2e5dfa2bcc" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://cbb83dda250db74285dcbe0b81bd0896acf402bac9710af090311f7360f824aa", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.10", + "podIPs": [ + { + "ip": "172.17.0.10" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:50.000Z" + } + } + ], + "replicaSets": [ + { + "metadata": { + "annotations": { + "deployment.kubernetes.io/desired-replicas": "10", + "deployment.kubernetes.io/max-replicas": "13", + "deployment.kubernetes.io/revision": "2" + }, + "creationTimestamp": "2020-09-24T11:39:26.000Z", + "generation": 3, + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "apps/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:deployment.kubernetes.io/desired-replicas": {}, + "f:deployment.kubernetes.io/max-replicas": {}, + "f:deployment.kubernetes.io/revision": {} + }, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"7551e949-42d1-4061-83c5-9da107186e47\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:replicas": {}, + "f:selector": { + "f:matchLabels": { + ".": {}, + "f:app": {}, + "f:pod-template-hash": {} + } + }, + "f:template": { + "f:metadata": { + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + } + }, + "f:status": { + "f:availableReplicas": {}, + "f:fullyLabeledReplicas": {}, + "f:observedGeneration": {}, + "f:readyReplicas": {}, + "f:replicas": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:55.000Z" + } + ], + "name": "dice-roller-6c8646bfd", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "Deployment", + "name": "dice-roller", + "uid": "7551e949-42d1-4061-83c5-9da107186e47" + } + ], + "resourceVersion": "593228", + "selfLink": "/apis/apps/v1/namespaces/default/replicasets/dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + }, + "spec": { + "replicas": 10, + "selector": { + "matchLabels": { + "app": "dice-roller", + "pod-template-hash": "6c8646bfd" + } + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + } + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + } + ], + "dnsPolicy": "ClusterFirst", + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "terminationGracePeriodSeconds": 30 + } + } + }, + "status": { + "availableReplicas": 10, + "fullyLabeledReplicas": 10, + "observedGeneration": 3, + "readyReplicas": 10, + "replicas": 10 + } + } + ], + "statefulsets": [ + { + "metadata": { + "annotations": { + "deployment.kubernetes.io/revision": "2", + "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"apps/v1\",\"kind\":\"StatefulSet\",\"metadata\":{\"annotations\":{},\"labels\":{\"backstage.io/kubernetes-id\":\"dice-roller\"},\"name\":\"dice-roller\",\"namespace\":\"default\"},\"spec\":{\"replicas\":10,\"selector\":{\"matchLabels\":{\"app\":\"dice-roller\"}},\"template\":{\"metadata\":{\"labels\":{\"app\":\"dice-roller\",\"backstage.io/kubernetes-id\":\"dice-roller\"}},\"spec\":{\"containers\":[{\"image\":\"nginx:1.14.2\",\"name\":\"nginx\",\"ports\":[{\"containerPort\":80}]}]}}}}\n" + }, + "creationTimestamp": "2020-09-23T12:00:55.000Z", + "generation": 3, + "labels": { + "backstage.io/kubernetes-id": "dice-roller" + }, + "managedFields": [ + { + "apiVersion": "apps/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:kubectl.kubernetes.io/last-applied-configuration": {} + }, + "f:labels": { + ".": {}, + "f:backstage.io/kubernetes-id": {} + } + }, + "f:spec": { + "f:progressDeadlineSeconds": {}, + "f:replicas": {}, + "f:revisionHistoryLimit": {}, + "f:selector": { + "f:matchLabels": { + ".": {}, + "f:app": {} + } + }, + "f:strategy": { + "f:rollingUpdate": { + ".": {}, + "f:maxSurge": {}, + "f:maxUnavailable": {} + }, + "f:type": {} + }, + "f:template": { + "f:metadata": { + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {} + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + } + } + }, + "manager": "kubectl", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "apps/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + "f:deployment.kubernetes.io/revision": {} + } + }, + "f:status": { + "f:availableReplicas": {}, + "f:conditions": { + ".": {}, + "k:{\"type\":\"Available\"}": { + ".": {}, + "f:lastTransitionTime": {}, + "f:lastUpdateTime": {}, + "f:message": {}, + "f:reason": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Progressing\"}": { + ".": {}, + "f:lastTransitionTime": {}, + "f:lastUpdateTime": {}, + "f:message": {}, + "f:reason": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:observedGeneration": {}, + "f:readyReplicas": {}, + "f:replicas": {}, + "f:updatedReplicas": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:55.000Z" + } + ], + "name": "dice-roller", + "namespace": "default", + "resourceVersion": "593230", + "selfLink": "/apis/apps/v1/namespaces/default/deployments/dice-roller", + "uid": "7551e949-42d1-4061-83c5-9da107186e47" + }, + "spec": { + "replicas": 10, + "revisionHistoryLimit": 10, + "selector": { + "matchLabels": { + "app": "dice-roller" + } + }, + "updateStrategy": { + "rollingUpdate": { + "maxSurge": "25%", + "maxUnavailable": "25%" + }, + "type": "RollingUpdate" + }, + "podManagementPolicy": "Parallel", + "serviceName": "dice-roller", + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller" + } + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + } + ], + "dnsPolicy": "ClusterFirst", + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "terminationGracePeriodSeconds": 30 + } + } + }, + "status": { + "availableReplicas": 10, + "conditions": [ + { + "lastTransitionTime": "2020-09-23T12:00:55.000Z", + "lastUpdateTime": "2020-09-24T11:39:28.000Z", + "message": "ReplicaSet \"dice-roller-6c8646bfd\" has successfully progressed.", + "reason": "NewReplicaSetAvailable", + "status": "True", + "type": "Progressing" + }, + { + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "lastUpdateTime": "2020-09-25T09:58:55.000Z", + "message": "Deployment has minimum availability.", + "reason": "MinimumReplicasAvailable", + "status": "True", + "type": "Available" + } + ], + "observedGeneration": 3, + "readyReplicas": 10, + "replicas": 10, + "updatedReplicas": 10 + } + } + ], + "horizontalPodAutoscalers": [ + { + "apiVersion": "autoscaling/v1", + "kind": "HorizontalPodAutoscaler", + "metadata": { + "annotations": { + "autoscaling.alpha.kubernetes.io/conditions": "[{\"type\":\"AbleToScale\",\"status\":\"True\",\"lastTransitionTime\":\"2021-01-05T10:26:04Z\",\"reason\":\"SucceededGetScale\",\"message\":\"the HPA controller was able to get the target's current scale\"},{\"type\":\"ScalingActive\",\"status\":\"False\",\"lastTransitionTime\":\"2021-01-05T10:26:04Z\",\"reason\":\"FailedGetResourceMetric\",\"message\":\"the HPA was unable to compute the replica count: unable to get metrics for resource cpu: no metrics returned from resource metrics API\"}]", + "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"autoscaling/v1\",\"kind\":\"HorizontalPodAutoscaler\",\"metadata\":{\"annotations\":{},\"labels\":{\"backstage.io/kubernetes-id\":\"dice-roller\"},\"name\":\"dice-roller\",\"namespace\":\"default\"},\"spec\":{\"maxReplicas\":15,\"minReplicas\":10,\"scaleTargetRef\":{\"apiVersion\":\"apps/v1\",\"kind\":\"Deployment\",\"name\":\"dice-roller\"},\"targetCPUUtilizationPercentage\":50}}\n" + }, + "creationTimestamp": "2021-01-05T10:25:48Z", + "labels": { + "backstage.io/kubernetes-id": "dice-roller" + }, + "managedFields": [ + { + "apiVersion": "autoscaling/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:kubectl.kubernetes.io/last-applied-configuration": {} + }, + "f:labels": { + ".": {}, + "f:backstage.io/kubernetes-id": {} + } + }, + "f:spec": { + "f:maxReplicas": {}, + "f:minReplicas": {}, + "f:scaleTargetRef": { + "f:apiVersion": {}, + "f:kind": {}, + "f:name": {} + }, + "f:targetCPUUtilizationPercentage": {} + } + }, + "manager": "kubectl-client-side-apply", + "operation": "Update", + "time": "2021-01-05T10:25:48Z" + }, + { + "apiVersion": "autoscaling/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + "f:autoscaling.alpha.kubernetes.io/conditions": {} + } + }, + "f:status": { + "f:currentReplicas": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2021-01-05T10:26:04Z" + } + ], + "name": "dice-roller", + "namespace": "default", + "resourceVersion": "598", + "selfLink": "/apis/autoscaling/v1/namespaces/default/horizontalpodautoscalers/dice-roller", + "uid": "dd7c5329-567c-43c2-b159-756808d90a8e" + }, + "spec": { + "maxReplicas": 15, + "minReplicas": 10, + "scaleTargetRef": { + "apiVersion": "apps/v1", + "kind": "Deployment", + "name": "dice-roller" + }, + "targetCPUUtilizationPercentage": 50 + }, + "status": { + "currentReplicas": 10, + "desiredReplicas": 0, + "currentCPUUtilizationPercentage": 30 + } + } + ] +} diff --git a/plugins/kubernetes-react/src/__fixtures__/2-cronjobs.json b/plugins/kubernetes-react/src/__fixtures__/2-cronjobs.json new file mode 100644 index 0000000000..6c087023b7 --- /dev/null +++ b/plugins/kubernetes-react/src/__fixtures__/2-cronjobs.json @@ -0,0 +1,385 @@ +{ + "cronJobs": [ + { + "metadata": { + "name": "dice-roller-cronjob", + "namespace": "default", + "uid": "9ea073bc-7a4b-4b99-8321-0305bce85568", + "resourceVersion": "1362732552", + "creationTimestamp": "2021-07-16T22:39:58Z", + "labels": { + "backstage.io/kubernetes-id": "dice-roller" + }, + "annotations": {} + }, + "spec": { + "schedule": "* */2 * * *", + "startingDeadlineSeconds": 1800, + "concurrencyPolicy": "Forbid", + "suspend": true, + "jobTemplate": { + "metadata": { "creationTimestamp": null }, + "spec": { + "backoffLimit": 2, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "backstage.io/kubernetes-id": "dice-roller" + }, + "annotations": {} + }, + "spec": { + "containers": [ + { + "name": "busybox", + "image": "busybox", + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "imagePullPolicy": "IfNotPresent", + "command": ["/bin/sh", "-c", "date; echo Rolling a die!"] + } + ], + "restartPolicy": "Never", + "terminationGracePeriodSeconds": 30, + "dnsPolicy": "ClusterFirst", + "securityContext": {}, + "schedulerName": "default-scheduler" + } + } + } + }, + "successfulJobsHistoryLimit": 2, + "failedJobsHistoryLimit": 2 + }, + "status": { + "lastScheduleTime": "2021-11-16T02:10:00Z" + } + } + ], + "jobs": [ + { + "metadata": { + "name": "dice-roller-cronjob-1637025000", + "namespace": "default", + "uid": "69d5d242-a9a4-47b8-b9c7-c536ae8f151a", + "resourceVersion": "1361029181", + "creationTimestamp": "2021-11-16T01:10:24Z", + "labels": { + "backstage.io/kubernetes-id": "dice-roller" + }, + "ownerReferences": [ + { + "apiVersion": "batch/v1", + "kind": "CronJob", + "name": "dice-roller-cronjob", + "uid": "9ea073bc-7a4b-4b99-8321-0305bce85568", + "controller": true, + "blockOwnerDeletion": true + } + ] + }, + "spec": { + "parallelism": 1, + "completions": 1, + "backoffLimit": 2, + "selector": { + "matchLabels": { + "controller-uid": "69d5d242-a9a4-47b8-b9c7-c536ae8f151a" + } + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "backstage.io/kubernetes-id": "dice-roller", + "controller-uid": "69d5d242-a9a4-47b8-b9c7-c536ae8f151a", + "job-name": "dice-roller-cronjob-1637025000" + }, + "annotations": {} + }, + "spec": { + "containers": [ + { + "command": ["/bin/sh", "-c", "date; echo Rolling a die!"], + "image": "busybox", + "imagePullPolicy": "IfNotPresent", + "name": "busybox", + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + } + ], + "restartPolicy": "Never", + "terminationGracePeriodSeconds": 30, + "dnsPolicy": "ClusterFirst", + "securityContext": {}, + "schedulerName": "default-scheduler" + } + } + }, + "status": { + "conditions": [ + { + "type": "Failed", + "status": "True", + "reason": "BackoffLimitExceeded", + "lastProbeTime": "2021-11-16T01:11:31Z", + "lastTransitionTime": "2021-11-16T01:11:31Z" + } + ], + "startTime": "2021-11-16T01:10:24Z", + "failed": 2 + } + } + ], + "pods": [ + { + "metadata": { + "name": "dice-roller-cronjob-1637025000-gstc4", + "generateName": "dice-roller-cronjob-1637025000-", + "namespace": "default", + "uid": "3b0f2b65-5ae2-441a-beda-bdc92bcafaf0", + "resourceVersion": "1361029179", + "creationTimestamp": "2021-11-16T01:10:24Z", + "labels": { + "backstage.io/kubernetes-id": "dice-roller", + "controller-uid": "69d5d242-a9a4-47b8-b9c7-c536ae8f151a", + "job-name": "dice-roller-cronjob-1637025000" + }, + "annotations": {}, + "ownerReferences": [ + { + "apiVersion": "batch/v1", + "kind": "Job", + "name": "dice-roller-cronjob-1637025000", + "uid": "69d5d242-a9a4-47b8-b9c7-c536ae8f151a", + "controller": true, + "blockOwnerDeletion": true + } + ] + }, + "spec": { + "volumes": [], + "containers": [ + { + "command": ["/bin/sh", "-c", "date; echo Rolling a die!"], + "image": "busybox", + "imagePullPolicy": "IfNotPresent", + "name": "busybox", + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + } + ], + "restartPolicy": "Never", + "terminationGracePeriodSeconds": 30, + "dnsPolicy": "ClusterFirst", + "serviceAccountName": "default", + "serviceAccount": "default", + "nodeName": "minikube", + "securityContext": {}, + "schedulerName": "default-scheduler", + "tolerations": [ + { + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "effect": "NoExecute", + "tolerationSeconds": 300 + }, + { + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "effect": "NoExecute", + "tolerationSeconds": 300 + } + ], + "priority": 0, + "enableServiceLinks": true + }, + "status": { + "phase": "Failed", + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2021-11-18T19:10:13Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2021-11-18T19:11:02Z", + "message": "containers with unready status: [busybox]", + "reason": "ContainersNotReady", + "status": "False", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2021-11-18T19:11:02Z", + "message": "containers with unready status: [busybox]", + "reason": "ContainersNotReady", + "status": "False", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2021-11-18T19:10:08Z", + "status": "True", + "type": "PodScheduled" + } + ], + "hostIP": "192.168.49.2", + "podIP": "172.17.0.25", + "podIPs": [{ "ip": "172.17.0.25" }], + "startTime": "2021-11-18T19:10:08Z", + "containerStatuses": [ + { + "name": "busybox", + "state": { + "terminated": { + "exitCode": 1, + "finishedAt": "2021-11-18T19:11:01Z", + "reason": "Error", + "startedAt": "2021-11-18T19:10:17Z", + "containerID": "docker://1062343e1bb3625e36717bc15617c1bbca976366c3c9dd87035c71f33d015615" + } + }, + "lastState": {}, + "ready": false, + "restartCount": 0, + "image": "busybox:latest", + "imageID": "docker-pullable://busybox@sha256:e7157b6d7ebbe2cce5eaa8cfe8aa4fa82d173999b9f90a9ec42e57323546c353", + "containerID": "docker://1062343e1bb3625e36717bc15617c1bbca976366c3c9dd87035c71f33d015615", + "started": false + } + ], + "qosClass": "Burstable" + } + }, + { + "metadata": { + "name": "dice-roller-cronjob-1637025000-p4mlc", + "generateName": "dice-roller-cronjob-1637025000-", + "namespace": "default", + "uid": "acddd5d2-ac7f-473b-a9d8-17a89f99ac39", + "resourceVersion": "1361174579", + "creationTimestamp": "2021-11-16T02:10:22Z", + "labels": { + "backstage.io/kubernetes-id": "dice-roller", + "controller-uid": "69d5d242-a9a4-47b8-b9c7-c536ae8f151a", + "job-name": "dice-roller-cronjob-1637025000" + }, + "annotations": {}, + "ownerReferences": [ + { + "apiVersion": "batch/v1", + "kind": "Job", + "name": "dice-roller-cronjob-1637025000", + "uid": "69d5d242-a9a4-47b8-b9c7-c536ae8f151a", + "controller": true, + "blockOwnerDeletion": true + } + ] + }, + "spec": { + "volumes": [], + "containers": [ + { + "command": ["/bin/sh", "-c", "date; echo Rolling a die!"], + "image": "busybox", + "imagePullPolicy": "IfNotPresent", + "name": "busybox", + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + } + ], + "restartPolicy": "Never", + "terminationGracePeriodSeconds": 30, + "dnsPolicy": "ClusterFirst", + "serviceAccountName": "default", + "serviceAccount": "default", + "nodeName": "minikube", + "securityContext": {}, + "schedulerName": "default-scheduler", + "tolerations": [ + { + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "effect": "NoExecute", + "tolerationSeconds": 300 + }, + { + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "effect": "NoExecute", + "tolerationSeconds": 300 + } + ], + "priority": 0, + "enableServiceLinks": true + }, + "status": { + "phase": "Failed", + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2021-11-18T19:10:13Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2021-11-18T19:11:02Z", + "message": "containers with unready status: [busybox]", + "reason": "ContainersNotReady", + "status": "False", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2021-11-18T19:11:02Z", + "message": "containers with unready status: [busybox]", + "reason": "ContainersNotReady", + "status": "False", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2021-11-18T19:10:08Z", + "status": "True", + "type": "PodScheduled" + } + ], + "hostIP": "192.168.49.2", + "podIP": "172.17.0.25", + "podIPs": [{ "ip": "172.17.0.25" }], + "startTime": "2021-11-16T02:10:22Z", + "containerStatuses": [ + { + "name": "busybox", + "state": { + "terminated": { + "exitCode": 1, + "finishedAt": "2021-11-18T19:11:01Z", + "reason": "Error", + "startedAt": "2021-11-18T19:10:17Z", + "containerID": "docker://2659c4d0f8a68f2b49863c18738322f1686d5b87275428e5e641fd9fd9e06739" + } + }, + "lastState": {}, + "ready": true, + "restartCount": 0, + "image": "busybox:latest", + "imageID": "docker-pullable://busybox@sha256:e7157b6d7ebbe2cce5eaa8cfe8aa4fa82d173999b9f90a9ec42e57323546c353", + "containerID": "docker://2659c4d0f8a68f2b49863c18738322f1686d5b87275428e5e641fd9fd9e06739", + "started": true + } + ], + "qosClass": "Burstable" + } + } + ] +} diff --git a/plugins/kubernetes-react/src/__fixtures__/2-deployments.json b/plugins/kubernetes-react/src/__fixtures__/2-deployments.json new file mode 100644 index 0000000000..f5efdbf1cb --- /dev/null +++ b/plugins/kubernetes-react/src/__fixtures__/2-deployments.json @@ -0,0 +1,4519 @@ +{ + "pods": [ + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.11\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:55.000Z" + } + ], + "name": "dice-roller-6c8646bfd-2m5hv", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593216", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-2m5hv", + "uid": "aadb71c0-36fa-43e3-b38a-162f134d4359" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://aa4489297c34c48bb33c18474a8d2b33854a82ed42155680b259f635f556ce70", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.11", + "podIPs": [ + { + "ip": "172.17.0.11" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:50.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.7\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:55.000Z" + } + ], + "name": "dice-roller-6c8646bfd-4v6s8", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593221", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-4v6s8", + "uid": "32e56490-6f20-4757-991f-a0c7fb407358" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://d91cc76c41249b8d3dfcf538d180b471b2a7966aae0d17a818307c8a9b4af897", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.7", + "podIPs": [ + { + "ip": "172.17.0.7" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:50.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-24T11:39:26.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-24T11:39:26.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.6\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-24T11:39:27.000Z" + } + ], + "name": "dice-roller-6c8646bfd-b9zt5", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "503886", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-b9zt5", + "uid": "8b6601b6-469e-4e89-8fd0-abb2f1a567e4" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:26.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:27.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:27.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:26.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://c50e0d0fa96f09a2ed5df7dd5a7f7de88e6b7c7addb8f002f299d6afc52d82ce", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-24T11:39:27.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.6", + "podIPs": [ + { + "ip": "172.17.0.6" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-24T11:39:26.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.13\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:55.000Z" + } + ], + "name": "dice-roller-6c8646bfd-cfxqc", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593211", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-cfxqc", + "uid": "e87e1776-0ca7-41fb-aeea-e1f648387545" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:51.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://c1641d986aae424429b7c2c1117baeb17d3794f73206bd57292cdf8264f929b2", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.13", + "podIPs": [ + { + "ip": "172.17.0.13" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:51.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.15\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:54.000Z" + } + ], + "name": "dice-roller-6c8646bfd-dtv5z", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593190", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-dtv5z", + "uid": "1638a41b-e47e-4c17-a1f7-7b447df248b6" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:51.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:53.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:53.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://e62c32db58dbfe0a74b2d2cba0e0a97b7f222693c68e930037ac8738c4758ca3", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.15", + "podIPs": [ + { + "ip": "172.17.0.15" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:51.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.12\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:53.000Z" + } + ], + "name": "dice-roller-6c8646bfd-hhts2", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593186", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-hhts2", + "uid": "ea0b147a-c56a-46e6-9445-7a0b1b0ed3c0" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:53.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:53.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://bcdbc153630f90556d57ff0d62f04d847ca63a5f0a7e5d9230683623d33d4b8d", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.12", + "podIPs": [ + { + "ip": "172.17.0.12" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:50.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.14\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:55.000Z" + } + ], + "name": "dice-roller-6c8646bfd-j68lm", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593226", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-j68lm", + "uid": "b230ff1d-7a13-479b-9c7b-77c26bd79f62" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://30fa8a3429f86ab8e9a4cec472b79d74266609082703f48950f4aae021e9d6a2", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.14", + "podIPs": [ + { + "ip": "172.17.0.14" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:50.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.9\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:53.000Z" + } + ], + "name": "dice-roller-6c8646bfd-m6f9w", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593181", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-m6f9w", + "uid": "9b0079f6-ff29-4619-bf6e-71cc10199ac5" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:53.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:53.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://f78767ee90eedffe46ff64bfe76d7f69426800dd89f3df012daf0baf3a9c5bdd", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.9", + "podIPs": [ + { + "ip": "172.17.0.9" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:50.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-24T11:39:27.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-24T11:39:27.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.4\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-24T11:39:28.000Z" + } + ], + "name": "dice-roller-6c8646bfd-nv9pk", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "503918", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-nv9pk", + "uid": "acf7f77f-78c6-4d4b-bc73-637211770ffc" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:27.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:28.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:28.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:27.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://63dec9b32942c4b09ae43d09d6978261f674a3ee623823b8f1d20da8044c12ac", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-24T11:39:28.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.4", + "podIPs": [ + { + "ip": "172.17.0.4" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-24T11:39:27.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.10\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:55.000Z" + } + ], + "name": "dice-roller-6c8646bfd-pjhfj", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593205", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-pjhfj", + "uid": "78775c3a-7af2-4ebe-a676-bc2e5dfa2bcc" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://cbb83dda250db74285dcbe0b81bd0896acf402bac9710af090311f7360f824aa", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.10", + "podIPs": [ + { + "ip": "172.17.0.10" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:50.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T10:34:01.000Z", + "generateName": "dice-roller-canary-7d64cd756c-", + "labels": { + "app": "dice-roller-canary", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "7d64cd756c" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"9208395b-a9a7-4e46-b881-6a189f7fbdb0\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + }, + "k:{\"name\":\"other-side-car\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":82,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + }, + "k:{\"name\":\"side-car\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":81,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T10:34:01.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:message": {}, + "f:reason": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:message": {}, + "f:reason": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.16\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T14:18:54.000Z" + } + ], + "name": "dice-roller-canary-7d64cd756c-55rfq", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-canary-7d64cd756c", + "uid": "9208395b-a9a7-4e46-b881-6a189f7fbdb0" + } + ], + "resourceVersion": "620452", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-canary-7d64cd756c-55rfq", + "uid": "65ad28e3-5d51-4b4b-9bf8-4cb069803034" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + }, + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "side-car", + "ports": [ + { + "containerPort": 81, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + }, + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "other-side-car", + "ports": [ + { + "containerPort": 82, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T10:34:01.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T14:18:53.000Z", + "message": "containers with unready status: [side-car other-side-car]", + "reason": "ContainersNotReady", + "status": "False", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T14:18:53.000Z", + "message": "containers with unready status: [side-car other-side-car]", + "reason": "ContainersNotReady", + "status": "False", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T10:34:01.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://6ce15178d114a85f3d2e832de45c3355ab5b71ed5f4d4d225ee1c83bf07f69d9", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T10:34:01.000Z" + } + } + }, + { + "containerID": "docker://b3ce93d7f90bfe22558c61d2505b8473580574accdebb5fa4e51c0729c3511f4", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": { + "terminated": { + "containerID": "docker://b3ce93d7f90bfe22558c61d2505b8473580574accdebb5fa4e51c0729c3511f4", + "exitCode": 1, + "finishedAt": "2020-09-25T14:18:52.000Z", + "reason": "Error", + "startedAt": "2020-09-25T14:18:50.000Z" + } + }, + "name": "other-side-car", + "ready": false, + "restartCount": 38, + "started": false, + "state": { + "waiting": { + "message": "back-off 5m0s restarting failed container=other-side-car pod=dice-roller-canary-7d64cd756c-55rfq_default(65ad28e3-5d51-4b4b-9bf8-4cb069803034)", + "reason": "CrashLoopBackOff" + } + } + }, + { + "containerID": "docker://b7f0e65a2b8ab48c5f234616cfe8286aa96b55c3ef09c5cfbc4cdbe67a96f8cb", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": { + "terminated": { + "containerID": "docker://b7f0e65a2b8ab48c5f234616cfe8286aa96b55c3ef09c5cfbc4cdbe67a96f8cb", + "exitCode": 1, + "finishedAt": "2020-09-25T14:18:52.000Z", + "reason": "Error", + "startedAt": "2020-09-25T14:18:50.000Z" + } + }, + "name": "side-car", + "ready": false, + "restartCount": 38, + "started": false, + "state": { + "waiting": { + "message": "back-off 5m0s restarting failed container=side-car pod=dice-roller-canary-7d64cd756c-55rfq_default(65ad28e3-5d51-4b4b-9bf8-4cb069803034)", + "reason": "CrashLoopBackOff" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.16", + "podIPs": [ + { + "ip": "172.17.0.16" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T10:34:01.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T10:34:02.000Z", + "generateName": "dice-roller-canary-7d64cd756c-", + "labels": { + "app": "dice-roller-canary", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "7d64cd756c" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"9208395b-a9a7-4e46-b881-6a189f7fbdb0\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + }, + "k:{\"name\":\"other-side-car\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":82,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + }, + "k:{\"name\":\"side-car\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":81,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T10:34:02.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:message": {}, + "f:reason": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:message": {}, + "f:reason": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.5\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T14:19:05.000Z" + } + ], + "name": "dice-roller-canary-7d64cd756c-vtbdx", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-canary-7d64cd756c", + "uid": "9208395b-a9a7-4e46-b881-6a189f7fbdb0" + } + ], + "resourceVersion": "620481", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-canary-7d64cd756c-vtbdx", + "uid": "0b8d9d79-b43d-4339-be57-ad5c63add77e" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + }, + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "side-car", + "ports": [ + { + "containerPort": 81, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + }, + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "other-side-car", + "ports": [ + { + "containerPort": 82, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T10:34:02.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T14:19:04.000Z", + "message": "containers with unready status: [side-car other-side-car]", + "reason": "ContainersNotReady", + "status": "False", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T14:19:04.000Z", + "message": "containers with unready status: [side-car other-side-car]", + "reason": "ContainersNotReady", + "status": "False", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T10:34:02.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://3f9cadc6f135247eb2df9aaca8f25ea05dcf42be86d58fb833c8acf192da0d66", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T10:34:03.000Z" + } + } + }, + { + "containerID": "docker://5e3a9f9129e5ce74fea249c013afcc056ee95a940fed24495ef9b58df67771f3", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": { + "terminated": { + "containerID": "docker://5e3a9f9129e5ce74fea249c013afcc056ee95a940fed24495ef9b58df67771f3", + "exitCode": 1, + "finishedAt": "2020-09-25T14:19:03.000Z", + "reason": "Error", + "startedAt": "2020-09-25T14:19:01.000Z" + } + }, + "name": "other-side-car", + "ready": false, + "restartCount": 38, + "started": false, + "state": { + "waiting": { + "message": "back-off 5m0s restarting failed container=other-side-car pod=dice-roller-canary-7d64cd756c-vtbdx_default(0b8d9d79-b43d-4339-be57-ad5c63add77e)", + "reason": "CrashLoopBackOff" + } + } + }, + { + "containerID": "docker://21b42cae298c0ed7f90373974d8c88b0941d17733f35398144a17ece32e03210", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": { + "terminated": { + "containerID": "docker://21b42cae298c0ed7f90373974d8c88b0941d17733f35398144a17ece32e03210", + "exitCode": 1, + "finishedAt": "2020-09-25T14:19:03.000Z", + "reason": "Error", + "startedAt": "2020-09-25T14:19:01.000Z" + } + }, + "name": "side-car", + "ready": false, + "restartCount": 38, + "started": false, + "state": { + "waiting": { + "message": "back-off 5m0s restarting failed container=side-car pod=dice-roller-canary-7d64cd756c-vtbdx_default(0b8d9d79-b43d-4339-be57-ad5c63add77e)", + "reason": "CrashLoopBackOff" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.5", + "podIPs": [ + { + "ip": "172.17.0.5" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T10:34:02.000Z" + } + } + ], + "replicaSets": [ + { + "metadata": { + "annotations": { + "deployment.kubernetes.io/desired-replicas": "10", + "deployment.kubernetes.io/max-replicas": "13", + "deployment.kubernetes.io/revision": "2" + }, + "creationTimestamp": "2020-09-24T11:39:26.000Z", + "generation": 3, + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "apps/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:deployment.kubernetes.io/desired-replicas": {}, + "f:deployment.kubernetes.io/max-replicas": {}, + "f:deployment.kubernetes.io/revision": {} + }, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"7551e949-42d1-4061-83c5-9da107186e47\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:replicas": {}, + "f:selector": { + "f:matchLabels": { + ".": {}, + "f:app": {}, + "f:pod-template-hash": {} + } + }, + "f:template": { + "f:metadata": { + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + } + }, + "f:status": { + "f:availableReplicas": {}, + "f:fullyLabeledReplicas": {}, + "f:observedGeneration": {}, + "f:readyReplicas": {}, + "f:replicas": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:55.000Z" + } + ], + "name": "dice-roller-6c8646bfd", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "Deployment", + "name": "dice-roller", + "uid": "7551e949-42d1-4061-83c5-9da107186e47" + } + ], + "resourceVersion": "593228", + "selfLink": "/apis/apps/v1/namespaces/default/replicasets/dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + }, + "spec": { + "replicas": 10, + "selector": { + "matchLabels": { + "app": "dice-roller", + "pod-template-hash": "6c8646bfd" + } + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + } + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + } + ], + "dnsPolicy": "ClusterFirst", + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "terminationGracePeriodSeconds": 30 + } + } + }, + "status": { + "availableReplicas": 10, + "fullyLabeledReplicas": 10, + "observedGeneration": 3, + "readyReplicas": 10, + "replicas": 10 + } + }, + { + "metadata": { + "annotations": { + "deployment.kubernetes.io/desired-replicas": "2", + "deployment.kubernetes.io/max-replicas": "3", + "deployment.kubernetes.io/revision": "3" + }, + "creationTimestamp": "2020-09-25T10:34:01.000Z", + "generation": 2, + "labels": { + "app": "dice-roller-canary", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "7d64cd756c" + }, + "managedFields": [ + { + "apiVersion": "apps/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:deployment.kubernetes.io/desired-replicas": {}, + "f:deployment.kubernetes.io/max-replicas": {}, + "f:deployment.kubernetes.io/revision": {} + }, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"0b6ae80f-999b-40e9-b116-ea925f0ed07b\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:replicas": {}, + "f:selector": { + "f:matchLabels": { + ".": {}, + "f:app": {}, + "f:pod-template-hash": {} + } + }, + "f:template": { + "f:metadata": { + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + }, + "k:{\"name\":\"other-side-car\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":82,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + }, + "k:{\"name\":\"side-car\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":81,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + } + }, + "f:status": { + "f:fullyLabeledReplicas": {}, + "f:observedGeneration": {}, + "f:replicas": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T14:19:01.000Z" + } + ], + "name": "dice-roller-canary-7d64cd756c", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "Deployment", + "name": "dice-roller-canary", + "uid": "0b6ae80f-999b-40e9-b116-ea925f0ed07b" + } + ], + "resourceVersion": "620479", + "selfLink": "/apis/apps/v1/namespaces/default/replicasets/dice-roller-canary-7d64cd756c", + "uid": "9208395b-a9a7-4e46-b881-6a189f7fbdb0" + }, + "spec": { + "replicas": 2, + "selector": { + "matchLabels": { + "app": "dice-roller-canary", + "pod-template-hash": "7d64cd756c" + } + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "app": "dice-roller-canary", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "7d64cd756c" + } + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + }, + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "side-car", + "ports": [ + { + "containerPort": 81, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + }, + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "other-side-car", + "ports": [ + { + "containerPort": 82, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + } + ], + "dnsPolicy": "ClusterFirst", + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "terminationGracePeriodSeconds": 30 + } + } + }, + "status": { + "fullyLabeledReplicas": 2, + "observedGeneration": 2, + "replicas": 2 + } + }, + { + "metadata": { + "annotations": { + "deployment.kubernetes.io/desired-replicas": "2", + "deployment.kubernetes.io/max-replicas": "3", + "deployment.kubernetes.io/revision": "2" + }, + "creationTimestamp": "2020-09-25T09:25:16.000Z", + "generation": 4, + "labels": { + "app": "dice-roller-canary", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "bcb8d54dd" + }, + "managedFields": [ + { + "apiVersion": "apps/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:deployment.kubernetes.io/desired-replicas": {}, + "f:deployment.kubernetes.io/max-replicas": {}, + "f:deployment.kubernetes.io/revision": {} + }, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"0b6ae80f-999b-40e9-b116-ea925f0ed07b\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:replicas": {}, + "f:selector": { + "f:matchLabels": { + ".": {}, + "f:app": {}, + "f:pod-template-hash": {} + } + }, + "f:template": { + "f:metadata": { + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + }, + "k:{\"name\":\"side-car\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":81,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + } + }, + "f:status": { + "f:observedGeneration": {}, + "f:replicas": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T10:34:04.000Z" + } + ], + "name": "dice-roller-canary-bcb8d54dd", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "Deployment", + "name": "dice-roller-canary", + "uid": "0b6ae80f-999b-40e9-b116-ea925f0ed07b" + } + ], + "resourceVersion": "598025", + "selfLink": "/apis/apps/v1/namespaces/default/replicasets/dice-roller-canary-bcb8d54dd", + "uid": "51942585-d599-42aa-bf23-9cf1acad4006" + }, + "spec": { + "replicas": 0, + "selector": { + "matchLabels": { + "app": "dice-roller-canary", + "pod-template-hash": "bcb8d54dd" + } + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "app": "dice-roller-canary", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "bcb8d54dd" + } + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + }, + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "side-car", + "ports": [ + { + "containerPort": 81, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + } + ], + "dnsPolicy": "ClusterFirst", + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "terminationGracePeriodSeconds": 30 + } + } + }, + "status": { + "observedGeneration": 4, + "replicas": 0 + } + }, + { + "metadata": { + "annotations": { + "deployment.kubernetes.io/desired-replicas": "2", + "deployment.kubernetes.io/max-replicas": "3", + "deployment.kubernetes.io/revision": "1" + }, + "creationTimestamp": "2020-09-25T09:02:53.000Z", + "generation": 3, + "labels": { + "app": "dice-roller-canary", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "c866fbf67" + }, + "managedFields": [ + { + "apiVersion": "apps/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:deployment.kubernetes.io/desired-replicas": {}, + "f:deployment.kubernetes.io/max-replicas": {}, + "f:deployment.kubernetes.io/revision": {} + }, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"0b6ae80f-999b-40e9-b116-ea925f0ed07b\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:replicas": {}, + "f:selector": { + "f:matchLabels": { + ".": {}, + "f:app": {}, + "f:pod-template-hash": {} + } + }, + "f:template": { + "f:metadata": { + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + } + }, + "f:status": { + "f:observedGeneration": {}, + "f:replicas": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:25:20.000Z" + } + ], + "name": "dice-roller-canary-c866fbf67", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "Deployment", + "name": "dice-roller-canary", + "uid": "0b6ae80f-999b-40e9-b116-ea925f0ed07b" + } + ], + "resourceVersion": "588501", + "selfLink": "/apis/apps/v1/namespaces/default/replicasets/dice-roller-canary-c866fbf67", + "uid": "4d2dfe13-978f-4504-9036-ca585acdea6c" + }, + "spec": { + "replicas": 0, + "selector": { + "matchLabels": { + "app": "dice-roller-canary", + "pod-template-hash": "c866fbf67" + } + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "app": "dice-roller-canary", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "c866fbf67" + } + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + } + ], + "dnsPolicy": "ClusterFirst", + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "terminationGracePeriodSeconds": 30 + } + } + }, + "status": { + "observedGeneration": 3, + "replicas": 0 + } + } + ], + "deployments": [ + { + "metadata": { + "annotations": { + "deployment.kubernetes.io/revision": "2", + "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"apps/v1\",\"kind\":\"Deployment\",\"metadata\":{\"annotations\":{},\"labels\":{\"backstage.io/kubernetes-id\":\"dice-roller\"},\"name\":\"dice-roller\",\"namespace\":\"default\"},\"spec\":{\"replicas\":10,\"selector\":{\"matchLabels\":{\"app\":\"dice-roller\"}},\"template\":{\"metadata\":{\"labels\":{\"app\":\"dice-roller\",\"backstage.io/kubernetes-id\":\"dice-roller\"}},\"spec\":{\"containers\":[{\"image\":\"nginx:1.14.2\",\"name\":\"nginx\",\"ports\":[{\"containerPort\":80}]}]}}}}\n" + }, + "creationTimestamp": "2020-09-23T12:00:55.000Z", + "generation": 3, + "labels": { + "backstage.io/kubernetes-id": "dice-roller" + }, + "managedFields": [ + { + "apiVersion": "apps/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:kubectl.kubernetes.io/last-applied-configuration": {} + }, + "f:labels": { + ".": {}, + "f:backstage.io/kubernetes-id": {} + } + }, + "f:spec": { + "f:progressDeadlineSeconds": {}, + "f:replicas": {}, + "f:revisionHistoryLimit": {}, + "f:selector": { + "f:matchLabels": { + ".": {}, + "f:app": {} + } + }, + "f:strategy": { + "f:rollingUpdate": { + ".": {}, + "f:maxSurge": {}, + "f:maxUnavailable": {} + }, + "f:type": {} + }, + "f:template": { + "f:metadata": { + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {} + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + } + } + }, + "manager": "kubectl", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "apps/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + "f:deployment.kubernetes.io/revision": {} + } + }, + "f:status": { + "f:availableReplicas": {}, + "f:conditions": { + ".": {}, + "k:{\"type\":\"Available\"}": { + ".": {}, + "f:lastTransitionTime": {}, + "f:lastUpdateTime": {}, + "f:message": {}, + "f:reason": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Progressing\"}": { + ".": {}, + "f:lastTransitionTime": {}, + "f:lastUpdateTime": {}, + "f:message": {}, + "f:reason": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:observedGeneration": {}, + "f:readyReplicas": {}, + "f:replicas": {}, + "f:updatedReplicas": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:55.000Z" + } + ], + "name": "dice-roller", + "namespace": "default", + "resourceVersion": "593230", + "selfLink": "/apis/apps/v1/namespaces/default/deployments/dice-roller", + "uid": "7551e949-42d1-4061-83c5-9da107186e47" + }, + "spec": { + "progressDeadlineSeconds": 600, + "replicas": 10, + "revisionHistoryLimit": 10, + "selector": { + "matchLabels": { + "app": "dice-roller" + } + }, + "strategy": { + "rollingUpdate": { + "maxSurge": "25%", + "maxUnavailable": "25%" + }, + "type": "RollingUpdate" + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller" + } + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + } + ], + "dnsPolicy": "ClusterFirst", + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "terminationGracePeriodSeconds": 30 + } + } + }, + "status": { + "availableReplicas": 10, + "conditions": [ + { + "lastTransitionTime": "2020-09-23T12:00:55.000Z", + "lastUpdateTime": "2020-09-24T11:39:28.000Z", + "message": "ReplicaSet \"dice-roller-6c8646bfd\" has successfully progressed.", + "reason": "NewReplicaSetAvailable", + "status": "True", + "type": "Progressing" + }, + { + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "lastUpdateTime": "2020-09-25T09:58:55.000Z", + "message": "Deployment has minimum availability.", + "reason": "MinimumReplicasAvailable", + "status": "True", + "type": "Available" + } + ], + "observedGeneration": 3, + "readyReplicas": 10, + "replicas": 10, + "updatedReplicas": 10 + } + }, + { + "metadata": { + "annotations": { + "deployment.kubernetes.io/revision": "3", + "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"apps/v1\",\"kind\":\"Deployment\",\"metadata\":{\"annotations\":{},\"labels\":{\"backstage.io/kubernetes-id\":\"dice-roller\"},\"name\":\"dice-roller-canary\",\"namespace\":\"default\"},\"spec\":{\"replicas\":2,\"selector\":{\"matchLabels\":{\"app\":\"dice-roller-canary\"}},\"template\":{\"metadata\":{\"labels\":{\"app\":\"dice-roller-canary\",\"backstage.io/kubernetes-id\":\"dice-roller\"}},\"spec\":{\"containers\":[{\"image\":\"nginx:1.14.2\",\"name\":\"nginx\",\"ports\":[{\"containerPort\":80}]},{\"image\":\"nginx:1.14.2\",\"name\":\"side-car\",\"ports\":[{\"containerPort\":81}]},{\"image\":\"nginx:1.14.2\",\"name\":\"other-side-car\",\"ports\":[{\"containerPort\":82}]}]}}}}\n" + }, + "creationTimestamp": "2020-09-25T09:02:53.000Z", + "generation": 3, + "labels": { + "backstage.io/kubernetes-id": "dice-roller" + }, + "managedFields": [ + { + "apiVersion": "apps/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:kubectl.kubernetes.io/last-applied-configuration": {} + }, + "f:labels": { + ".": {}, + "f:backstage.io/kubernetes-id": {} + } + }, + "f:spec": { + "f:progressDeadlineSeconds": {}, + "f:replicas": {}, + "f:revisionHistoryLimit": {}, + "f:selector": { + "f:matchLabels": { + ".": {}, + "f:app": {} + } + }, + "f:strategy": { + "f:rollingUpdate": { + ".": {}, + "f:maxSurge": {}, + "f:maxUnavailable": {} + }, + "f:type": {} + }, + "f:template": { + "f:metadata": { + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {} + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + }, + "k:{\"name\":\"other-side-car\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":82,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + }, + "k:{\"name\":\"side-car\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":81,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + } + } + }, + "manager": "kubectl", + "operation": "Update", + "time": "2020-09-25T10:34:01.000Z" + }, + { + "apiVersion": "apps/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + "f:deployment.kubernetes.io/revision": {} + } + }, + "f:status": { + "f:conditions": { + ".": {}, + "k:{\"type\":\"Available\"}": { + ".": {}, + "f:lastTransitionTime": {}, + "f:lastUpdateTime": {}, + "f:message": {}, + "f:reason": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Progressing\"}": { + ".": {}, + "f:lastTransitionTime": {}, + "f:lastUpdateTime": {}, + "f:message": {}, + "f:reason": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:observedGeneration": {}, + "f:replicas": {}, + "f:unavailableReplicas": {}, + "f:updatedReplicas": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T14:19:04.000Z" + } + ], + "name": "dice-roller-canary", + "namespace": "default", + "resourceVersion": "620480", + "selfLink": "/apis/apps/v1/namespaces/default/deployments/dice-roller-canary", + "uid": "0b6ae80f-999b-40e9-b116-ea925f0ed07b" + }, + "spec": { + "progressDeadlineSeconds": 600, + "replicas": 2, + "revisionHistoryLimit": 10, + "selector": { + "matchLabels": { + "app": "dice-roller-canary" + } + }, + "strategy": { + "rollingUpdate": { + "maxSurge": "25%", + "maxUnavailable": "25%" + }, + "type": "RollingUpdate" + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "app": "dice-roller-canary", + "backstage.io/kubernetes-id": "dice-roller" + } + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + }, + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "side-car", + "ports": [ + { + "containerPort": 81, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + }, + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "other-side-car", + "ports": [ + { + "containerPort": 82, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + } + ], + "dnsPolicy": "ClusterFirst", + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "terminationGracePeriodSeconds": 30 + } + } + }, + "status": { + "conditions": [ + { + "lastTransitionTime": "2020-09-25T09:02:53.000Z", + "lastUpdateTime": "2020-09-25T10:34:04.000Z", + "message": "ReplicaSet \"dice-roller-canary-7d64cd756c\" has successfully progressed.", + "reason": "NewReplicaSetAvailable", + "status": "True", + "type": "Progressing" + }, + { + "lastTransitionTime": "2020-09-25T13:48:06.000Z", + "lastUpdateTime": "2020-09-25T13:48:06.000Z", + "message": "Deployment does not have minimum availability.", + "reason": "MinimumReplicasUnavailable", + "status": "False", + "type": "Available" + } + ], + "observedGeneration": 3, + "replicas": 2, + "unavailableReplicas": 2, + "updatedReplicas": 2 + } + } + ], + "horizontalPodAutoscalers": [ + { + "apiVersion": "autoscaling/v1", + "kind": "HorizontalPodAutoscaler", + "metadata": { + "annotations": { + "autoscaling.alpha.kubernetes.io/conditions": "[{\"type\":\"AbleToScale\",\"status\":\"True\",\"lastTransitionTime\":\"2021-01-05T10:26:04Z\",\"reason\":\"SucceededGetScale\",\"message\":\"the HPA controller was able to get the target's current scale\"},{\"type\":\"ScalingActive\",\"status\":\"False\",\"lastTransitionTime\":\"2021-01-05T10:26:04Z\",\"reason\":\"FailedGetResourceMetric\",\"message\":\"the HPA was unable to compute the replica count: unable to get metrics for resource cpu: no metrics returned from resource metrics API\"}]", + "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"autoscaling/v1\",\"kind\":\"HorizontalPodAutoscaler\",\"metadata\":{\"annotations\":{},\"labels\":{\"backstage.io/kubernetes-id\":\"dice-roller\"},\"name\":\"dice-roller\",\"namespace\":\"default\"},\"spec\":{\"maxReplicas\":15,\"minReplicas\":10,\"scaleTargetRef\":{\"apiVersion\":\"apps/v1\",\"kind\":\"Deployment\",\"name\":\"dice-roller\"},\"targetCPUUtilizationPercentage\":50}}\n" + }, + "creationTimestamp": "2021-01-05T10:25:48Z", + "labels": { + "backstage.io/kubernetes-id": "dice-roller" + }, + "managedFields": [ + { + "apiVersion": "autoscaling/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:kubectl.kubernetes.io/last-applied-configuration": {} + }, + "f:labels": { + ".": {}, + "f:backstage.io/kubernetes-id": {} + } + }, + "f:spec": { + "f:maxReplicas": {}, + "f:minReplicas": {}, + "f:scaleTargetRef": { + "f:apiVersion": {}, + "f:kind": {}, + "f:name": {} + }, + "f:targetCPUUtilizationPercentage": {} + } + }, + "manager": "kubectl-client-side-apply", + "operation": "Update", + "time": "2021-01-05T10:25:48Z" + }, + { + "apiVersion": "autoscaling/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + "f:autoscaling.alpha.kubernetes.io/conditions": {} + } + }, + "f:status": { + "f:currentReplicas": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2021-01-05T10:26:04Z" + } + ], + "name": "dice-roller", + "namespace": "default", + "resourceVersion": "598", + "selfLink": "/apis/autoscaling/v1/namespaces/default/horizontalpodautoscalers/dice-roller", + "uid": "dd7c5329-567c-43c2-b159-756808d90a8e" + }, + "spec": { + "maxReplicas": 15, + "minReplicas": 10, + "scaleTargetRef": { + "apiVersion": "apps/v1", + "kind": "Deployment", + "name": "dice-roller" + }, + "targetCPUUtilizationPercentage": 50 + }, + "status": { + "currentReplicas": 10, + "desiredReplicas": 0, + "currentCPUUtilizationPercentage": 30 + } + } + ] +} diff --git a/plugins/kubernetes-react/src/__fixtures__/2-statefulsets.json b/plugins/kubernetes-react/src/__fixtures__/2-statefulsets.json new file mode 100644 index 0000000000..0a8c26c198 --- /dev/null +++ b/plugins/kubernetes-react/src/__fixtures__/2-statefulsets.json @@ -0,0 +1,4521 @@ +{ + "pods": [ + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.11\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:55.000Z" + } + ], + "name": "dice-roller-6c8646bfd-2m5hv", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "StatefulSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593216", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-2m5hv", + "uid": "aadb71c0-36fa-43e3-b38a-162f134d4359" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://aa4489297c34c48bb33c18474a8d2b33854a82ed42155680b259f635f556ce70", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.11", + "podIPs": [ + { + "ip": "172.17.0.11" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:50.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.7\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:55.000Z" + } + ], + "name": "dice-roller-6c8646bfd-4v6s8", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593221", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-4v6s8", + "uid": "32e56490-6f20-4757-991f-a0c7fb407358" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://d91cc76c41249b8d3dfcf538d180b471b2a7966aae0d17a818307c8a9b4af897", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.7", + "podIPs": [ + { + "ip": "172.17.0.7" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:50.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-24T11:39:26.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-24T11:39:26.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.6\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-24T11:39:27.000Z" + } + ], + "name": "dice-roller-6c8646bfd-b9zt5", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "503886", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-b9zt5", + "uid": "8b6601b6-469e-4e89-8fd0-abb2f1a567e4" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:26.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:27.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:27.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:26.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://c50e0d0fa96f09a2ed5df7dd5a7f7de88e6b7c7addb8f002f299d6afc52d82ce", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-24T11:39:27.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.6", + "podIPs": [ + { + "ip": "172.17.0.6" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-24T11:39:26.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.13\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:55.000Z" + } + ], + "name": "dice-roller-6c8646bfd-cfxqc", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593211", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-cfxqc", + "uid": "e87e1776-0ca7-41fb-aeea-e1f648387545" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:51.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://c1641d986aae424429b7c2c1117baeb17d3794f73206bd57292cdf8264f929b2", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.13", + "podIPs": [ + { + "ip": "172.17.0.13" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:51.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.15\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:54.000Z" + } + ], + "name": "dice-roller-6c8646bfd-dtv5z", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593190", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-dtv5z", + "uid": "1638a41b-e47e-4c17-a1f7-7b447df248b6" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:51.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:53.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:53.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://e62c32db58dbfe0a74b2d2cba0e0a97b7f222693c68e930037ac8738c4758ca3", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.15", + "podIPs": [ + { + "ip": "172.17.0.15" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:51.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.12\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:53.000Z" + } + ], + "name": "dice-roller-6c8646bfd-hhts2", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593186", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-hhts2", + "uid": "ea0b147a-c56a-46e6-9445-7a0b1b0ed3c0" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:53.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:53.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://bcdbc153630f90556d57ff0d62f04d847ca63a5f0a7e5d9230683623d33d4b8d", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.12", + "podIPs": [ + { + "ip": "172.17.0.12" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:50.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.14\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:55.000Z" + } + ], + "name": "dice-roller-6c8646bfd-j68lm", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593226", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-j68lm", + "uid": "b230ff1d-7a13-479b-9c7b-77c26bd79f62" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://30fa8a3429f86ab8e9a4cec472b79d74266609082703f48950f4aae021e9d6a2", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.14", + "podIPs": [ + { + "ip": "172.17.0.14" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:50.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.9\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:53.000Z" + } + ], + "name": "dice-roller-6c8646bfd-m6f9w", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593181", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-m6f9w", + "uid": "9b0079f6-ff29-4619-bf6e-71cc10199ac5" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:53.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:53.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://f78767ee90eedffe46ff64bfe76d7f69426800dd89f3df012daf0baf3a9c5bdd", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.9", + "podIPs": [ + { + "ip": "172.17.0.9" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:50.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-24T11:39:27.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-24T11:39:27.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.4\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-24T11:39:28.000Z" + } + ], + "name": "dice-roller-6c8646bfd-nv9pk", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "503918", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-nv9pk", + "uid": "acf7f77f-78c6-4d4b-bc73-637211770ffc" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:27.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:28.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:28.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:27.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://63dec9b32942c4b09ae43d09d6978261f674a3ee623823b8f1d20da8044c12ac", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-24T11:39:28.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.4", + "podIPs": [ + { + "ip": "172.17.0.4" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-24T11:39:27.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.10\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:55.000Z" + } + ], + "name": "dice-roller-6c8646bfd-pjhfj", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593205", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-pjhfj", + "uid": "78775c3a-7af2-4ebe-a676-bc2e5dfa2bcc" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://cbb83dda250db74285dcbe0b81bd0896acf402bac9710af090311f7360f824aa", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.10", + "podIPs": [ + { + "ip": "172.17.0.10" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:50.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T10:34:01.000Z", + "generateName": "dice-roller-canary-7d64cd756c-", + "labels": { + "app": "dice-roller-canary", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "7d64cd756c" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"9208395b-a9a7-4e46-b881-6a189f7fbdb0\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + }, + "k:{\"name\":\"other-side-car\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":82,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + }, + "k:{\"name\":\"side-car\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":81,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T10:34:01.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:message": {}, + "f:reason": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:message": {}, + "f:reason": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.16\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T14:18:54.000Z" + } + ], + "name": "dice-roller-canary-7d64cd756c-55rfq", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-canary-7d64cd756c", + "uid": "9208395b-a9a7-4e46-b881-6a189f7fbdb0" + } + ], + "resourceVersion": "620452", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-canary-7d64cd756c-55rfq", + "uid": "65ad28e3-5d51-4b4b-9bf8-4cb069803034" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + }, + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "side-car", + "ports": [ + { + "containerPort": 81, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + }, + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "other-side-car", + "ports": [ + { + "containerPort": 82, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T10:34:01.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T14:18:53.000Z", + "message": "containers with unready status: [side-car other-side-car]", + "reason": "ContainersNotReady", + "status": "False", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T14:18:53.000Z", + "message": "containers with unready status: [side-car other-side-car]", + "reason": "ContainersNotReady", + "status": "False", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T10:34:01.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://6ce15178d114a85f3d2e832de45c3355ab5b71ed5f4d4d225ee1c83bf07f69d9", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T10:34:01.000Z" + } + } + }, + { + "containerID": "docker://b3ce93d7f90bfe22558c61d2505b8473580574accdebb5fa4e51c0729c3511f4", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": { + "terminated": { + "containerID": "docker://b3ce93d7f90bfe22558c61d2505b8473580574accdebb5fa4e51c0729c3511f4", + "exitCode": 1, + "finishedAt": "2020-09-25T14:18:52.000Z", + "reason": "Error", + "startedAt": "2020-09-25T14:18:50.000Z" + } + }, + "name": "other-side-car", + "ready": false, + "restartCount": 38, + "started": false, + "state": { + "waiting": { + "message": "back-off 5m0s restarting failed container=other-side-car pod=dice-roller-canary-7d64cd756c-55rfq_default(65ad28e3-5d51-4b4b-9bf8-4cb069803034)", + "reason": "CrashLoopBackOff" + } + } + }, + { + "containerID": "docker://b7f0e65a2b8ab48c5f234616cfe8286aa96b55c3ef09c5cfbc4cdbe67a96f8cb", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": { + "terminated": { + "containerID": "docker://b7f0e65a2b8ab48c5f234616cfe8286aa96b55c3ef09c5cfbc4cdbe67a96f8cb", + "exitCode": 1, + "finishedAt": "2020-09-25T14:18:52.000Z", + "reason": "Error", + "startedAt": "2020-09-25T14:18:50.000Z" + } + }, + "name": "side-car", + "ready": false, + "restartCount": 38, + "started": false, + "state": { + "waiting": { + "message": "back-off 5m0s restarting failed container=side-car pod=dice-roller-canary-7d64cd756c-55rfq_default(65ad28e3-5d51-4b4b-9bf8-4cb069803034)", + "reason": "CrashLoopBackOff" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.16", + "podIPs": [ + { + "ip": "172.17.0.16" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T10:34:01.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T10:34:02.000Z", + "generateName": "dice-roller-canary-7d64cd756c-", + "labels": { + "app": "dice-roller-canary", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "7d64cd756c" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"9208395b-a9a7-4e46-b881-6a189f7fbdb0\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + }, + "k:{\"name\":\"other-side-car\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":82,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + }, + "k:{\"name\":\"side-car\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":81,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T10:34:02.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:message": {}, + "f:reason": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:message": {}, + "f:reason": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.5\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T14:19:05.000Z" + } + ], + "name": "dice-roller-canary-7d64cd756c-vtbdx", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-canary-7d64cd756c", + "uid": "9208395b-a9a7-4e46-b881-6a189f7fbdb0" + } + ], + "resourceVersion": "620481", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-canary-7d64cd756c-vtbdx", + "uid": "0b8d9d79-b43d-4339-be57-ad5c63add77e" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + }, + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "side-car", + "ports": [ + { + "containerPort": 81, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + }, + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "other-side-car", + "ports": [ + { + "containerPort": 82, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T10:34:02.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T14:19:04.000Z", + "message": "containers with unready status: [side-car other-side-car]", + "reason": "ContainersNotReady", + "status": "False", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T14:19:04.000Z", + "message": "containers with unready status: [side-car other-side-car]", + "reason": "ContainersNotReady", + "status": "False", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T10:34:02.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://3f9cadc6f135247eb2df9aaca8f25ea05dcf42be86d58fb833c8acf192da0d66", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T10:34:03.000Z" + } + } + }, + { + "containerID": "docker://5e3a9f9129e5ce74fea249c013afcc056ee95a940fed24495ef9b58df67771f3", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": { + "terminated": { + "containerID": "docker://5e3a9f9129e5ce74fea249c013afcc056ee95a940fed24495ef9b58df67771f3", + "exitCode": 1, + "finishedAt": "2020-09-25T14:19:03.000Z", + "reason": "Error", + "startedAt": "2020-09-25T14:19:01.000Z" + } + }, + "name": "other-side-car", + "ready": false, + "restartCount": 38, + "started": false, + "state": { + "waiting": { + "message": "back-off 5m0s restarting failed container=other-side-car pod=dice-roller-canary-7d64cd756c-vtbdx_default(0b8d9d79-b43d-4339-be57-ad5c63add77e)", + "reason": "CrashLoopBackOff" + } + } + }, + { + "containerID": "docker://21b42cae298c0ed7f90373974d8c88b0941d17733f35398144a17ece32e03210", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": { + "terminated": { + "containerID": "docker://21b42cae298c0ed7f90373974d8c88b0941d17733f35398144a17ece32e03210", + "exitCode": 1, + "finishedAt": "2020-09-25T14:19:03.000Z", + "reason": "Error", + "startedAt": "2020-09-25T14:19:01.000Z" + } + }, + "name": "side-car", + "ready": false, + "restartCount": 38, + "started": false, + "state": { + "waiting": { + "message": "back-off 5m0s restarting failed container=side-car pod=dice-roller-canary-7d64cd756c-vtbdx_default(0b8d9d79-b43d-4339-be57-ad5c63add77e)", + "reason": "CrashLoopBackOff" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.5", + "podIPs": [ + { + "ip": "172.17.0.5" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T10:34:02.000Z" + } + } + ], + "replicaSets": [ + { + "metadata": { + "annotations": { + "deployment.kubernetes.io/desired-replicas": "10", + "deployment.kubernetes.io/max-replicas": "13", + "deployment.kubernetes.io/revision": "2" + }, + "creationTimestamp": "2020-09-24T11:39:26.000Z", + "generation": 3, + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "apps/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:deployment.kubernetes.io/desired-replicas": {}, + "f:deployment.kubernetes.io/max-replicas": {}, + "f:deployment.kubernetes.io/revision": {} + }, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"7551e949-42d1-4061-83c5-9da107186e47\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:replicas": {}, + "f:selector": { + "f:matchLabels": { + ".": {}, + "f:app": {}, + "f:pod-template-hash": {} + } + }, + "f:template": { + "f:metadata": { + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + } + }, + "f:status": { + "f:availableReplicas": {}, + "f:fullyLabeledReplicas": {}, + "f:observedGeneration": {}, + "f:readyReplicas": {}, + "f:replicas": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:55.000Z" + } + ], + "name": "dice-roller-6c8646bfd", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "Deployment", + "name": "dice-roller", + "uid": "7551e949-42d1-4061-83c5-9da107186e47" + } + ], + "resourceVersion": "593228", + "selfLink": "/apis/apps/v1/namespaces/default/replicasets/dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + }, + "spec": { + "replicas": 10, + "selector": { + "matchLabels": { + "app": "dice-roller", + "pod-template-hash": "6c8646bfd" + } + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + } + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + } + ], + "dnsPolicy": "ClusterFirst", + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "terminationGracePeriodSeconds": 30 + } + } + }, + "status": { + "availableReplicas": 10, + "fullyLabeledReplicas": 10, + "observedGeneration": 3, + "readyReplicas": 10, + "replicas": 10 + } + }, + { + "metadata": { + "annotations": { + "deployment.kubernetes.io/desired-replicas": "2", + "deployment.kubernetes.io/max-replicas": "3", + "deployment.kubernetes.io/revision": "3" + }, + "creationTimestamp": "2020-09-25T10:34:01.000Z", + "generation": 2, + "labels": { + "app": "dice-roller-canary", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "7d64cd756c" + }, + "managedFields": [ + { + "apiVersion": "apps/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:deployment.kubernetes.io/desired-replicas": {}, + "f:deployment.kubernetes.io/max-replicas": {}, + "f:deployment.kubernetes.io/revision": {} + }, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"0b6ae80f-999b-40e9-b116-ea925f0ed07b\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:replicas": {}, + "f:selector": { + "f:matchLabels": { + ".": {}, + "f:app": {}, + "f:pod-template-hash": {} + } + }, + "f:template": { + "f:metadata": { + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + }, + "k:{\"name\":\"other-side-car\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":82,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + }, + "k:{\"name\":\"side-car\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":81,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + } + }, + "f:status": { + "f:fullyLabeledReplicas": {}, + "f:observedGeneration": {}, + "f:replicas": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T14:19:01.000Z" + } + ], + "name": "dice-roller-canary-7d64cd756c", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "Deployment", + "name": "dice-roller-canary", + "uid": "0b6ae80f-999b-40e9-b116-ea925f0ed07b" + } + ], + "resourceVersion": "620479", + "selfLink": "/apis/apps/v1/namespaces/default/replicasets/dice-roller-canary-7d64cd756c", + "uid": "9208395b-a9a7-4e46-b881-6a189f7fbdb0" + }, + "spec": { + "replicas": 2, + "selector": { + "matchLabels": { + "app": "dice-roller-canary", + "pod-template-hash": "7d64cd756c" + } + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "app": "dice-roller-canary", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "7d64cd756c" + } + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + }, + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "side-car", + "ports": [ + { + "containerPort": 81, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + }, + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "other-side-car", + "ports": [ + { + "containerPort": 82, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + } + ], + "dnsPolicy": "ClusterFirst", + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "terminationGracePeriodSeconds": 30 + } + } + }, + "status": { + "fullyLabeledReplicas": 2, + "observedGeneration": 2, + "replicas": 2 + } + }, + { + "metadata": { + "annotations": { + "deployment.kubernetes.io/desired-replicas": "2", + "deployment.kubernetes.io/max-replicas": "3", + "deployment.kubernetes.io/revision": "2" + }, + "creationTimestamp": "2020-09-25T09:25:16.000Z", + "generation": 4, + "labels": { + "app": "dice-roller-canary", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "bcb8d54dd" + }, + "managedFields": [ + { + "apiVersion": "apps/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:deployment.kubernetes.io/desired-replicas": {}, + "f:deployment.kubernetes.io/max-replicas": {}, + "f:deployment.kubernetes.io/revision": {} + }, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"0b6ae80f-999b-40e9-b116-ea925f0ed07b\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:replicas": {}, + "f:selector": { + "f:matchLabels": { + ".": {}, + "f:app": {}, + "f:pod-template-hash": {} + } + }, + "f:template": { + "f:metadata": { + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + }, + "k:{\"name\":\"side-car\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":81,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + } + }, + "f:status": { + "f:observedGeneration": {}, + "f:replicas": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T10:34:04.000Z" + } + ], + "name": "dice-roller-canary-bcb8d54dd", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "Deployment", + "name": "dice-roller-canary", + "uid": "0b6ae80f-999b-40e9-b116-ea925f0ed07b" + } + ], + "resourceVersion": "598025", + "selfLink": "/apis/apps/v1/namespaces/default/replicasets/dice-roller-canary-bcb8d54dd", + "uid": "51942585-d599-42aa-bf23-9cf1acad4006" + }, + "spec": { + "replicas": 0, + "selector": { + "matchLabels": { + "app": "dice-roller-canary", + "pod-template-hash": "bcb8d54dd" + } + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "app": "dice-roller-canary", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "bcb8d54dd" + } + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + }, + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "side-car", + "ports": [ + { + "containerPort": 81, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + } + ], + "dnsPolicy": "ClusterFirst", + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "terminationGracePeriodSeconds": 30 + } + } + }, + "status": { + "observedGeneration": 4, + "replicas": 0 + } + }, + { + "metadata": { + "annotations": { + "deployment.kubernetes.io/desired-replicas": "2", + "deployment.kubernetes.io/max-replicas": "3", + "deployment.kubernetes.io/revision": "1" + }, + "creationTimestamp": "2020-09-25T09:02:53.000Z", + "generation": 3, + "labels": { + "app": "dice-roller-canary", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "c866fbf67" + }, + "managedFields": [ + { + "apiVersion": "apps/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:deployment.kubernetes.io/desired-replicas": {}, + "f:deployment.kubernetes.io/max-replicas": {}, + "f:deployment.kubernetes.io/revision": {} + }, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"0b6ae80f-999b-40e9-b116-ea925f0ed07b\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:replicas": {}, + "f:selector": { + "f:matchLabels": { + ".": {}, + "f:app": {}, + "f:pod-template-hash": {} + } + }, + "f:template": { + "f:metadata": { + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + } + }, + "f:status": { + "f:observedGeneration": {}, + "f:replicas": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:25:20.000Z" + } + ], + "name": "dice-roller-canary-c866fbf67", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "Deployment", + "name": "dice-roller-canary", + "uid": "0b6ae80f-999b-40e9-b116-ea925f0ed07b" + } + ], + "resourceVersion": "588501", + "selfLink": "/apis/apps/v1/namespaces/default/replicasets/dice-roller-canary-c866fbf67", + "uid": "4d2dfe13-978f-4504-9036-ca585acdea6c" + }, + "spec": { + "replicas": 0, + "selector": { + "matchLabels": { + "app": "dice-roller-canary", + "pod-template-hash": "c866fbf67" + } + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "app": "dice-roller-canary", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "c866fbf67" + } + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + } + ], + "dnsPolicy": "ClusterFirst", + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "terminationGracePeriodSeconds": 30 + } + } + }, + "status": { + "observedGeneration": 3, + "replicas": 0 + } + } + ], + "statefulsets": [ + { + "metadata": { + "annotations": { + "deployment.kubernetes.io/revision": "2", + "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"apps/v1\",\"kind\":\"StatefulSet\",\"metadata\":{\"annotations\":{},\"labels\":{\"backstage.io/kubernetes-id\":\"dice-roller\"},\"name\":\"dice-roller\",\"namespace\":\"default\"},\"spec\":{\"replicas\":10,\"selector\":{\"matchLabels\":{\"app\":\"dice-roller\"}},\"template\":{\"metadata\":{\"labels\":{\"app\":\"dice-roller\",\"backstage.io/kubernetes-id\":\"dice-roller\"}},\"spec\":{\"containers\":[{\"image\":\"nginx:1.14.2\",\"name\":\"nginx\",\"ports\":[{\"containerPort\":80}]}]}}}}\n" + }, + "creationTimestamp": "2020-09-23T12:00:55.000Z", + "generation": 3, + "labels": { + "backstage.io/kubernetes-id": "dice-roller" + }, + "managedFields": [ + { + "apiVersion": "apps/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:kubectl.kubernetes.io/last-applied-configuration": {} + }, + "f:labels": { + ".": {}, + "f:backstage.io/kubernetes-id": {} + } + }, + "f:spec": { + "f:progressDeadlineSeconds": {}, + "f:replicas": {}, + "f:revisionHistoryLimit": {}, + "f:selector": { + "f:matchLabels": { + ".": {}, + "f:app": {} + } + }, + "f:strategy": { + "f:rollingUpdate": { + ".": {}, + "f:maxSurge": {}, + "f:maxUnavailable": {} + }, + "f:type": {} + }, + "f:template": { + "f:metadata": { + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {} + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + } + } + }, + "manager": "kubectl", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "apps/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + "f:deployment.kubernetes.io/revision": {} + } + }, + "f:status": { + "f:availableReplicas": {}, + "f:conditions": { + ".": {}, + "k:{\"type\":\"Available\"}": { + ".": {}, + "f:lastTransitionTime": {}, + "f:lastUpdateTime": {}, + "f:message": {}, + "f:reason": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Progressing\"}": { + ".": {}, + "f:lastTransitionTime": {}, + "f:lastUpdateTime": {}, + "f:message": {}, + "f:reason": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:observedGeneration": {}, + "f:readyReplicas": {}, + "f:replicas": {}, + "f:updatedReplicas": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:55.000Z" + } + ], + "name": "dice-roller", + "namespace": "default", + "resourceVersion": "593230", + "selfLink": "/apis/apps/v1/namespaces/default/statefulsets/dice-roller", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + }, + "spec": { + "replicas": 10, + "revisionHistoryLimit": 10, + "selector": { + "matchLabels": { + "app": "dice-roller" + } + }, + "updateStrategy": { + "rollingUpdate": { + "maxSurge": "25%", + "maxUnavailable": "25%" + }, + "type": "RollingUpdate" + }, + "podManagementPolicy": "Parallel", + "serviceName": "dice-roller", + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller" + } + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + } + ], + "dnsPolicy": "ClusterFirst", + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "terminationGracePeriodSeconds": 30 + } + } + }, + "status": { + "availableReplicas": 10, + "conditions": [ + { + "lastTransitionTime": "2020-09-23T12:00:55.000Z", + "lastUpdateTime": "2020-09-24T11:39:28.000Z", + "message": "ReplicaSet \"dice-roller-6c8646bfd\" has successfully progressed.", + "reason": "NewReplicaSetAvailable", + "status": "True", + "type": "Progressing" + }, + { + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "lastUpdateTime": "2020-09-25T09:58:55.000Z", + "message": "Deployment has minimum availability.", + "reason": "MinimumReplicasAvailable", + "status": "True", + "type": "Available" + } + ], + "observedGeneration": 3, + "readyReplicas": 10, + "replicas": 10, + "updatedReplicas": 10 + } + }, + { + "metadata": { + "annotations": { + "deployment.kubernetes.io/revision": "3", + "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"apps/v1\",\"kind\":\"StatefulSet\",\"metadata\":{\"annotations\":{},\"labels\":{\"backstage.io/kubernetes-id\":\"dice-roller\"},\"name\":\"dice-roller-canary\",\"namespace\":\"default\"},\"spec\":{\"replicas\":2,\"selector\":{\"matchLabels\":{\"app\":\"dice-roller-canary\"}},\"template\":{\"metadata\":{\"labels\":{\"app\":\"dice-roller-canary\",\"backstage.io/kubernetes-id\":\"dice-roller\"}},\"spec\":{\"containers\":[{\"image\":\"nginx:1.14.2\",\"name\":\"nginx\",\"ports\":[{\"containerPort\":80}]},{\"image\":\"nginx:1.14.2\",\"name\":\"side-car\",\"ports\":[{\"containerPort\":81}]},{\"image\":\"nginx:1.14.2\",\"name\":\"other-side-car\",\"ports\":[{\"containerPort\":82}]}]}}}}\n" + }, + "creationTimestamp": "2020-09-25T09:02:53.000Z", + "generation": 3, + "labels": { + "backstage.io/kubernetes-id": "dice-roller" + }, + "managedFields": [ + { + "apiVersion": "apps/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:kubectl.kubernetes.io/last-applied-configuration": {} + }, + "f:labels": { + ".": {}, + "f:backstage.io/kubernetes-id": {} + } + }, + "f:spec": { + "f:progressDeadlineSeconds": {}, + "f:replicas": {}, + "f:revisionHistoryLimit": {}, + "f:selector": { + "f:matchLabels": { + ".": {}, + "f:app": {} + } + }, + "f:strategy": { + "f:rollingUpdate": { + ".": {}, + "f:maxSurge": {}, + "f:maxUnavailable": {} + }, + "f:type": {} + }, + "f:template": { + "f:metadata": { + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {} + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + }, + "k:{\"name\":\"other-side-car\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":82,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + }, + "k:{\"name\":\"side-car\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":81,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + } + } + }, + "manager": "kubectl", + "operation": "Update", + "time": "2020-09-25T10:34:01.000Z" + }, + { + "apiVersion": "apps/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + "f:deployment.kubernetes.io/revision": {} + } + }, + "f:status": { + "f:conditions": { + ".": {}, + "k:{\"type\":\"Available\"}": { + ".": {}, + "f:lastTransitionTime": {}, + "f:lastUpdateTime": {}, + "f:message": {}, + "f:reason": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Progressing\"}": { + ".": {}, + "f:lastTransitionTime": {}, + "f:lastUpdateTime": {}, + "f:message": {}, + "f:reason": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:observedGeneration": {}, + "f:replicas": {}, + "f:unavailableReplicas": {}, + "f:updatedReplicas": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T14:19:04.000Z" + } + ], + "name": "dice-roller-canary", + "namespace": "default", + "resourceVersion": "620480", + "selfLink": "/apis/apps/v1/namespaces/default/statefulsets/dice-roller-canary", + "uid": "9208395b-a9a7-4e46-b881-6a189f7fbdb0" + }, + "spec": { + "replicas": 2, + "revisionHistoryLimit": 10, + "selector": { + "matchLabels": { + "app": "dice-roller-canary" + } + }, + "updateStrategy": { + "rollingUpdate": { + "maxSurge": "25%", + "maxUnavailable": "25%" + }, + "type": "RollingUpdate" + }, + "podManagementPolicy": "Parallel", + "serviceName": "dice-roller", + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "app": "dice-roller-canary", + "backstage.io/kubernetes-id": "dice-roller" + } + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + }, + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "side-car", + "ports": [ + { + "containerPort": 81, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + }, + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "other-side-car", + "ports": [ + { + "containerPort": 82, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + } + ], + "dnsPolicy": "ClusterFirst", + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "terminationGracePeriodSeconds": 30 + } + } + }, + "status": { + "conditions": [ + { + "lastTransitionTime": "2020-09-25T09:02:53.000Z", + "lastUpdateTime": "2020-09-25T10:34:04.000Z", + "message": "ReplicaSet \"dice-roller-canary-7d64cd756c\" has successfully progressed.", + "reason": "NewReplicaSetAvailable", + "status": "True", + "type": "Progressing" + }, + { + "lastTransitionTime": "2020-09-25T13:48:06.000Z", + "lastUpdateTime": "2020-09-25T13:48:06.000Z", + "message": "Deployment does not have minimum availability.", + "reason": "MinimumReplicasUnavailable", + "status": "False", + "type": "Available" + } + ], + "observedGeneration": 3, + "replicas": 2, + "unavailableReplicas": 2, + "updatedReplicas": 2 + } + } + ], + "horizontalPodAutoscalers": [ + { + "apiVersion": "autoscaling/v1", + "kind": "HorizontalPodAutoscaler", + "metadata": { + "annotations": { + "autoscaling.alpha.kubernetes.io/conditions": "[{\"type\":\"AbleToScale\",\"status\":\"True\",\"lastTransitionTime\":\"2021-01-05T10:26:04Z\",\"reason\":\"SucceededGetScale\",\"message\":\"the HPA controller was able to get the target's current scale\"},{\"type\":\"ScalingActive\",\"status\":\"False\",\"lastTransitionTime\":\"2021-01-05T10:26:04Z\",\"reason\":\"FailedGetResourceMetric\",\"message\":\"the HPA was unable to compute the replica count: unable to get metrics for resource cpu: no metrics returned from resource metrics API\"}]", + "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"autoscaling/v1\",\"kind\":\"HorizontalPodAutoscaler\",\"metadata\":{\"annotations\":{},\"labels\":{\"backstage.io/kubernetes-id\":\"dice-roller\"},\"name\":\"dice-roller\",\"namespace\":\"default\"},\"spec\":{\"maxReplicas\":15,\"minReplicas\":10,\"scaleTargetRef\":{\"apiVersion\":\"apps/v1\",\"kind\":\"Deployment\",\"name\":\"dice-roller\"},\"targetCPUUtilizationPercentage\":50}}\n" + }, + "creationTimestamp": "2021-01-05T10:25:48Z", + "labels": { + "backstage.io/kubernetes-id": "dice-roller" + }, + "managedFields": [ + { + "apiVersion": "autoscaling/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:kubectl.kubernetes.io/last-applied-configuration": {} + }, + "f:labels": { + ".": {}, + "f:backstage.io/kubernetes-id": {} + } + }, + "f:spec": { + "f:maxReplicas": {}, + "f:minReplicas": {}, + "f:scaleTargetRef": { + "f:apiVersion": {}, + "f:kind": {}, + "f:name": {} + }, + "f:targetCPUUtilizationPercentage": {} + } + }, + "manager": "kubectl-client-side-apply", + "operation": "Update", + "time": "2021-01-05T10:25:48Z" + }, + { + "apiVersion": "autoscaling/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + "f:autoscaling.alpha.kubernetes.io/conditions": {} + } + }, + "f:status": { + "f:currentReplicas": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2021-01-05T10:26:04Z" + } + ], + "name": "dice-roller", + "namespace": "default", + "resourceVersion": "598", + "selfLink": "/apis/autoscaling/v1/namespaces/default/horizontalpodautoscalers/dice-roller", + "uid": "dd7c5329-567c-43c2-b159-756808d90a8e" + }, + "spec": { + "maxReplicas": 15, + "minReplicas": 10, + "scaleTargetRef": { + "apiVersion": "apps/v1", + "kind": "Deployment", + "name": "dice-roller" + }, + "targetCPUUtilizationPercentage": 50 + }, + "status": { + "currentReplicas": 10, + "desiredReplicas": 0, + "currentCPUUtilizationPercentage": 30 + } + } + ] +} diff --git a/plugins/kubernetes/src/api/KubernetesBackendClient.test.ts b/plugins/kubernetes-react/src/api/KubernetesBackendClient.test.ts similarity index 100% rename from plugins/kubernetes/src/api/KubernetesBackendClient.test.ts rename to plugins/kubernetes-react/src/api/KubernetesBackendClient.test.ts diff --git a/plugins/kubernetes/src/api/KubernetesBackendClient.ts b/plugins/kubernetes-react/src/api/KubernetesBackendClient.ts similarity index 99% rename from plugins/kubernetes/src/api/KubernetesBackendClient.ts rename to plugins/kubernetes-react/src/api/KubernetesBackendClient.ts index 681daa0ac0..b483c267d8 100644 --- a/plugins/kubernetes/src/api/KubernetesBackendClient.ts +++ b/plugins/kubernetes-react/src/api/KubernetesBackendClient.ts @@ -26,6 +26,7 @@ import { stringifyEntityRef } from '@backstage/catalog-model'; import { KubernetesAuthProvidersApi } from '../kubernetes-auth-provider'; import { NotFoundError } from '@backstage/errors'; +/** @public */ export class KubernetesBackendClient implements KubernetesApi { private readonly discoveryApi: DiscoveryApi; private readonly identityApi: IdentityApi; diff --git a/plugins/kubernetes/src/api/KubernetesProxyClient.test.ts b/plugins/kubernetes-react/src/api/KubernetesProxyClient.test.ts similarity index 100% rename from plugins/kubernetes/src/api/KubernetesProxyClient.test.ts rename to plugins/kubernetes-react/src/api/KubernetesProxyClient.test.ts diff --git a/plugins/kubernetes/src/api/KubernetesProxyClient.ts b/plugins/kubernetes-react/src/api/KubernetesProxyClient.ts similarity index 100% rename from plugins/kubernetes/src/api/KubernetesProxyClient.ts rename to plugins/kubernetes-react/src/api/KubernetesProxyClient.ts diff --git a/plugins/kubernetes/src/api/index.ts b/plugins/kubernetes-react/src/api/index.ts similarity index 100% rename from plugins/kubernetes/src/api/index.ts rename to plugins/kubernetes-react/src/api/index.ts diff --git a/plugins/kubernetes/src/api/types.ts b/plugins/kubernetes-react/src/api/types.ts similarity index 97% rename from plugins/kubernetes/src/api/types.ts rename to plugins/kubernetes-react/src/api/types.ts index 6065e47169..c0f97ffd41 100644 --- a/plugins/kubernetes/src/api/types.ts +++ b/plugins/kubernetes-react/src/api/types.ts @@ -23,14 +23,17 @@ import { import { createApiRef } from '@backstage/core-plugin-api'; import { Event } from 'kubernetes-models/v1'; +/** @public */ export const kubernetesApiRef = createApiRef({ id: 'plugin.kubernetes.service', }); +/** @public */ export const kubernetesProxyApiRef = createApiRef({ id: 'plugin.kubernetes.proxy-service', }); +/** @public */ export interface KubernetesApi { getObjectsByEntity( requestBody: KubernetesRequestBody, @@ -55,6 +58,7 @@ export interface KubernetesApi { }): Promise; } +/** @public */ export interface KubernetesProxyApi { getPodLogs(request: { podName: string; diff --git a/plugins/kubernetes/src/components/Cluster/Cluster.test.tsx b/plugins/kubernetes-react/src/components/Cluster/Cluster.test.tsx similarity index 100% rename from plugins/kubernetes/src/components/Cluster/Cluster.test.tsx rename to plugins/kubernetes-react/src/components/Cluster/Cluster.test.tsx diff --git a/plugins/kubernetes/src/components/Cluster/Cluster.tsx b/plugins/kubernetes-react/src/components/Cluster/Cluster.tsx similarity index 96% rename from plugins/kubernetes/src/components/Cluster/Cluster.tsx rename to plugins/kubernetes-react/src/components/Cluster/Cluster.tsx index bea7a46d37..42f1aca3a0 100644 --- a/plugins/kubernetes/src/components/Cluster/Cluster.tsx +++ b/plugins/kubernetes-react/src/components/Cluster/Cluster.tsx @@ -25,11 +25,11 @@ import { import { ClientPodStatus, ClusterObjects, + groupResponses, } from '@backstage/plugin-kubernetes-common'; import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; import { DeploymentsAccordions } from '../DeploymentsAccordions'; import { StatefulSetsAccordions } from '../StatefulSetsAccordions'; -import { groupResponses } from '../../utils/response'; import { IngressesAccordions } from '../IngressesAccordions'; import { ServicesAccordions } from '../ServicesAccordions'; import { CronJobsAccordions } from '../CronJobsAccordions'; @@ -103,12 +103,22 @@ const ClusterSummary = ({ ); }; -type ClusterProps = { +/** + * Props for Cluster + * + * @public + */ +export type ClusterProps = { clusterObjects: ClusterObjects; podsWithErrors: Set; children?: React.ReactNode; }; +/** + * Component for rendering Kubernetes resources in a cluster + * + * @public + */ export const Cluster = ({ clusterObjects, podsWithErrors }: ClusterProps) => { const groupedResponses = groupResponses(clusterObjects.resources); diff --git a/plugins/kubernetes/src/components/ErrorPanel/index.ts b/plugins/kubernetes-react/src/components/Cluster/index.ts similarity index 93% rename from plugins/kubernetes/src/components/ErrorPanel/index.ts rename to plugins/kubernetes-react/src/components/Cluster/index.ts index 2d3778e2c2..eac1e358b6 100644 --- a/plugins/kubernetes/src/components/ErrorPanel/index.ts +++ b/plugins/kubernetes-react/src/components/Cluster/index.ts @@ -13,4 +13,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export { ErrorPanel } from './ErrorPanel'; +export * from './Cluster'; diff --git a/plugins/kubernetes/src/components/CronJobsAccordions/CronJobsAccordions.test.tsx b/plugins/kubernetes-react/src/components/CronJobsAccordions/CronJobsAccordions.test.tsx similarity index 100% rename from plugins/kubernetes/src/components/CronJobsAccordions/CronJobsAccordions.test.tsx rename to plugins/kubernetes-react/src/components/CronJobsAccordions/CronJobsAccordions.test.tsx diff --git a/plugins/kubernetes/src/components/CronJobsAccordions/CronJobsAccordions.tsx b/plugins/kubernetes-react/src/components/CronJobsAccordions/CronJobsAccordions.tsx similarity index 97% rename from plugins/kubernetes/src/components/CronJobsAccordions/CronJobsAccordions.tsx rename to plugins/kubernetes-react/src/components/CronJobsAccordions/CronJobsAccordions.tsx index c5babe67fc..e724c14fdf 100644 --- a/plugins/kubernetes/src/components/CronJobsAccordions/CronJobsAccordions.tsx +++ b/plugins/kubernetes-react/src/components/CronJobsAccordions/CronJobsAccordions.tsx @@ -30,7 +30,12 @@ import { GroupedResponsesContext } from '../../hooks'; import { StatusError, StatusOK } from '@backstage/core-components'; import { humanizeCron } from '../../utils/crons'; -type CronJobsAccordionsProps = { +/** + * + * + * @public + */ +export type CronJobsAccordionsProps = { children?: React.ReactNode; }; @@ -101,6 +106,11 @@ const CronJobAccordion = ({ cronJob, ownedJobs }: CronJobAccordionProps) => { ); }; +/** + * + * + * @public + */ export const CronJobsAccordions = ({}: CronJobsAccordionsProps) => { const groupedResponses = useContext(GroupedResponsesContext); diff --git a/plugins/kubernetes/src/components/CronJobsAccordions/CronJobsDrawer.test.tsx b/plugins/kubernetes-react/src/components/CronJobsAccordions/CronJobsDrawer.test.tsx similarity index 100% rename from plugins/kubernetes/src/components/CronJobsAccordions/CronJobsDrawer.test.tsx rename to plugins/kubernetes-react/src/components/CronJobsAccordions/CronJobsDrawer.test.tsx diff --git a/plugins/kubernetes/src/components/CronJobsAccordions/CronJobsDrawer.tsx b/plugins/kubernetes-react/src/components/CronJobsAccordions/CronJobsDrawer.tsx similarity index 100% rename from plugins/kubernetes/src/components/CronJobsAccordions/CronJobsDrawer.tsx rename to plugins/kubernetes-react/src/components/CronJobsAccordions/CronJobsDrawer.tsx diff --git a/plugins/kubernetes/src/components/JobsAccordions/index.ts b/plugins/kubernetes-react/src/components/CronJobsAccordions/index.ts similarity index 92% rename from plugins/kubernetes/src/components/JobsAccordions/index.ts rename to plugins/kubernetes-react/src/components/CronJobsAccordions/index.ts index 392309de79..ecc7172523 100644 --- a/plugins/kubernetes/src/components/JobsAccordions/index.ts +++ b/plugins/kubernetes-react/src/components/CronJobsAccordions/index.ts @@ -13,4 +13,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export { JobsAccordions } from './JobsAccordions'; +export * from './CronJobsAccordions'; diff --git a/plugins/kubernetes/src/components/CustomResources/ArgoRollouts/Rollout.test.tsx b/plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/Rollout.test.tsx similarity index 100% rename from plugins/kubernetes/src/components/CustomResources/ArgoRollouts/Rollout.test.tsx rename to plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/Rollout.test.tsx diff --git a/plugins/kubernetes/src/components/CustomResources/ArgoRollouts/Rollout.tsx b/plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/Rollout.tsx similarity index 100% rename from plugins/kubernetes/src/components/CustomResources/ArgoRollouts/Rollout.tsx rename to plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/Rollout.tsx diff --git a/plugins/kubernetes/src/components/CustomResources/ArgoRollouts/RolloutDrawer.tsx b/plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/RolloutDrawer.tsx similarity index 100% rename from plugins/kubernetes/src/components/CustomResources/ArgoRollouts/RolloutDrawer.tsx rename to plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/RolloutDrawer.tsx diff --git a/plugins/kubernetes/src/components/CustomResources/ArgoRollouts/StepsProgress.test.tsx b/plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/StepsProgress.test.tsx similarity index 100% rename from plugins/kubernetes/src/components/CustomResources/ArgoRollouts/StepsProgress.test.tsx rename to plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/StepsProgress.test.tsx diff --git a/plugins/kubernetes/src/components/CustomResources/ArgoRollouts/StepsProgress.tsx b/plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/StepsProgress.tsx similarity index 100% rename from plugins/kubernetes/src/components/CustomResources/ArgoRollouts/StepsProgress.tsx rename to plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/StepsProgress.tsx diff --git a/plugins/kubernetes/src/components/CustomResources/ArgoRollouts/__fixtures__/aborted-rollout.json b/plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/__fixtures__/aborted-rollout.json similarity index 100% rename from plugins/kubernetes/src/components/CustomResources/ArgoRollouts/__fixtures__/aborted-rollout.json rename to plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/__fixtures__/aborted-rollout.json diff --git a/plugins/kubernetes/src/components/CustomResources/ArgoRollouts/__fixtures__/analysis-steps.ts b/plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/__fixtures__/analysis-steps.ts similarity index 100% rename from plugins/kubernetes/src/components/CustomResources/ArgoRollouts/__fixtures__/analysis-steps.ts rename to plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/__fixtures__/analysis-steps.ts diff --git a/plugins/kubernetes/src/components/CustomResources/ArgoRollouts/__fixtures__/grouped-resources.json b/plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/__fixtures__/grouped-resources.json similarity index 100% rename from plugins/kubernetes/src/components/CustomResources/ArgoRollouts/__fixtures__/grouped-resources.json rename to plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/__fixtures__/grouped-resources.json diff --git a/plugins/kubernetes/src/components/CustomResources/ArgoRollouts/__fixtures__/pause-steps.ts b/plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/__fixtures__/pause-steps.ts similarity index 100% rename from plugins/kubernetes/src/components/CustomResources/ArgoRollouts/__fixtures__/pause-steps.ts rename to plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/__fixtures__/pause-steps.ts diff --git a/plugins/kubernetes/src/components/CustomResources/ArgoRollouts/__fixtures__/paused-rollout.json b/plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/__fixtures__/paused-rollout.json similarity index 100% rename from plugins/kubernetes/src/components/CustomResources/ArgoRollouts/__fixtures__/paused-rollout.json rename to plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/__fixtures__/paused-rollout.json diff --git a/plugins/kubernetes/src/components/CustomResources/ArgoRollouts/__fixtures__/rollout.json b/plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/__fixtures__/rollout.json similarity index 100% rename from plugins/kubernetes/src/components/CustomResources/ArgoRollouts/__fixtures__/rollout.json rename to plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/__fixtures__/rollout.json diff --git a/plugins/kubernetes/src/components/CustomResources/ArgoRollouts/__fixtures__/setweight-steps.ts b/plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/__fixtures__/setweight-steps.ts similarity index 100% rename from plugins/kubernetes/src/components/CustomResources/ArgoRollouts/__fixtures__/setweight-steps.ts rename to plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/__fixtures__/setweight-steps.ts diff --git a/plugins/kubernetes/src/components/CustomResources/ArgoRollouts/index.ts b/plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/index.ts similarity index 100% rename from plugins/kubernetes/src/components/CustomResources/ArgoRollouts/index.ts rename to plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/index.ts diff --git a/plugins/kubernetes/src/components/CustomResources/ArgoRollouts/types.ts b/plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/types.ts similarity index 100% rename from plugins/kubernetes/src/components/CustomResources/ArgoRollouts/types.ts rename to plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/types.ts diff --git a/plugins/kubernetes/src/components/CustomResources/CustomResources.tsx b/plugins/kubernetes-react/src/components/CustomResources/CustomResources.tsx similarity index 95% rename from plugins/kubernetes/src/components/CustomResources/CustomResources.tsx rename to plugins/kubernetes-react/src/components/CustomResources/CustomResources.tsx index 436e97fce8..f204f5fdd1 100644 --- a/plugins/kubernetes/src/components/CustomResources/CustomResources.tsx +++ b/plugins/kubernetes-react/src/components/CustomResources/CustomResources.tsx @@ -20,7 +20,12 @@ import { RolloutAccordions } from './ArgoRollouts'; import { DefaultCustomResourceAccordions } from './DefaultCustomResource'; import { GroupedResponsesContext } from '../../hooks'; -interface CustomResourcesProps { +/** + * + * + * @public + */ +export interface CustomResourcesProps { children?: React.ReactNode; } @@ -30,6 +35,11 @@ const kindToResource = (customResources: any[]): Dictionary => { }); }; +/** + * + * + * @public + */ export const CustomResources = ({}: CustomResourcesProps) => { const groupedResponses = useContext(GroupedResponsesContext); const kindToResourceMap = kindToResource(groupedResponses.customResources); diff --git a/plugins/kubernetes/src/components/CustomResources/DefaultCustomResource.test.tsx b/plugins/kubernetes-react/src/components/CustomResources/DefaultCustomResource.test.tsx similarity index 100% rename from plugins/kubernetes/src/components/CustomResources/DefaultCustomResource.test.tsx rename to plugins/kubernetes-react/src/components/CustomResources/DefaultCustomResource.test.tsx diff --git a/plugins/kubernetes/src/components/CustomResources/DefaultCustomResource.tsx b/plugins/kubernetes-react/src/components/CustomResources/DefaultCustomResource.tsx similarity index 100% rename from plugins/kubernetes/src/components/CustomResources/DefaultCustomResource.tsx rename to plugins/kubernetes-react/src/components/CustomResources/DefaultCustomResource.tsx diff --git a/plugins/kubernetes/src/components/CustomResources/DefaultCustomResourceDrawer.tsx b/plugins/kubernetes-react/src/components/CustomResources/DefaultCustomResourceDrawer.tsx similarity index 100% rename from plugins/kubernetes/src/components/CustomResources/DefaultCustomResourceDrawer.tsx rename to plugins/kubernetes-react/src/components/CustomResources/DefaultCustomResourceDrawer.tsx diff --git a/plugins/kubernetes/src/components/CustomResources/__fixtures__/analysis-run.json b/plugins/kubernetes-react/src/components/CustomResources/__fixtures__/analysis-run.json similarity index 100% rename from plugins/kubernetes/src/components/CustomResources/__fixtures__/analysis-run.json rename to plugins/kubernetes-react/src/components/CustomResources/__fixtures__/analysis-run.json diff --git a/plugins/kubernetes/src/components/ErrorReporting/index.ts b/plugins/kubernetes-react/src/components/CustomResources/index.ts similarity index 92% rename from plugins/kubernetes/src/components/ErrorReporting/index.ts rename to plugins/kubernetes-react/src/components/CustomResources/index.ts index 451d08ec76..0c5e0ce7a0 100644 --- a/plugins/kubernetes/src/components/ErrorReporting/index.ts +++ b/plugins/kubernetes-react/src/components/CustomResources/index.ts @@ -13,4 +13,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export { ErrorReporting } from './ErrorReporting'; +export * from './CustomResources'; diff --git a/plugins/kubernetes/src/components/DeploymentsAccordions/DeploymentDrawer.test.tsx b/plugins/kubernetes-react/src/components/DeploymentsAccordions/DeploymentDrawer.test.tsx similarity index 100% rename from plugins/kubernetes/src/components/DeploymentsAccordions/DeploymentDrawer.test.tsx rename to plugins/kubernetes-react/src/components/DeploymentsAccordions/DeploymentDrawer.test.tsx diff --git a/plugins/kubernetes/src/components/DeploymentsAccordions/DeploymentDrawer.tsx b/plugins/kubernetes-react/src/components/DeploymentsAccordions/DeploymentDrawer.tsx similarity index 100% rename from plugins/kubernetes/src/components/DeploymentsAccordions/DeploymentDrawer.tsx rename to plugins/kubernetes-react/src/components/DeploymentsAccordions/DeploymentDrawer.tsx diff --git a/plugins/kubernetes/src/components/DeploymentsAccordions/DeploymentsAccordions.test.tsx b/plugins/kubernetes-react/src/components/DeploymentsAccordions/DeploymentsAccordions.test.tsx similarity index 100% rename from plugins/kubernetes/src/components/DeploymentsAccordions/DeploymentsAccordions.test.tsx rename to plugins/kubernetes-react/src/components/DeploymentsAccordions/DeploymentsAccordions.test.tsx diff --git a/plugins/kubernetes/src/components/DeploymentsAccordions/DeploymentsAccordions.tsx b/plugins/kubernetes-react/src/components/DeploymentsAccordions/DeploymentsAccordions.tsx similarity index 100% rename from plugins/kubernetes/src/components/DeploymentsAccordions/DeploymentsAccordions.tsx rename to plugins/kubernetes-react/src/components/DeploymentsAccordions/DeploymentsAccordions.tsx diff --git a/plugins/kubernetes/src/components/DeploymentsAccordions/index.ts b/plugins/kubernetes-react/src/components/DeploymentsAccordions/index.ts similarity index 100% rename from plugins/kubernetes/src/components/DeploymentsAccordions/index.ts rename to plugins/kubernetes-react/src/components/DeploymentsAccordions/index.ts diff --git a/plugins/kubernetes/src/components/ErrorPanel/ErrorPanel.test.tsx b/plugins/kubernetes-react/src/components/ErrorPanel/ErrorPanel.test.tsx similarity index 100% rename from plugins/kubernetes/src/components/ErrorPanel/ErrorPanel.test.tsx rename to plugins/kubernetes-react/src/components/ErrorPanel/ErrorPanel.test.tsx diff --git a/plugins/kubernetes/src/components/ErrorPanel/ErrorPanel.tsx b/plugins/kubernetes-react/src/components/ErrorPanel/ErrorPanel.tsx similarity index 96% rename from plugins/kubernetes/src/components/ErrorPanel/ErrorPanel.tsx rename to plugins/kubernetes-react/src/components/ErrorPanel/ErrorPanel.tsx index d2cb88b9ca..b02f4c18dc 100644 --- a/plugins/kubernetes/src/components/ErrorPanel/ErrorPanel.tsx +++ b/plugins/kubernetes-react/src/components/ErrorPanel/ErrorPanel.tsx @@ -41,13 +41,23 @@ const clustersWithErrorsToErrorMessage = ( }); }; -type ErrorPanelProps = { +/** + * + * + * @public + */ +export type ErrorPanelProps = { entityName: string; errorMessage?: string; clustersWithErrors?: ClusterObjects[]; children?: React.ReactNode; }; +/** + * + * + * @public + */ export const ErrorPanel = ({ entityName, errorMessage, diff --git a/plugins/kubernetes/src/components/CustomResources/index.ts b/plugins/kubernetes-react/src/components/ErrorPanel/index.ts similarity index 91% rename from plugins/kubernetes/src/components/CustomResources/index.ts rename to plugins/kubernetes-react/src/components/ErrorPanel/index.ts index 9297fd8ac1..94d6e5b028 100644 --- a/plugins/kubernetes/src/components/CustomResources/index.ts +++ b/plugins/kubernetes-react/src/components/ErrorPanel/index.ts @@ -13,4 +13,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export { CustomResources } from './CustomResources'; +export * from './ErrorPanel'; diff --git a/plugins/kubernetes/src/components/ErrorReporting/ErrorReporting.tsx b/plugins/kubernetes-react/src/components/ErrorReporting/ErrorReporting.tsx similarity index 92% rename from plugins/kubernetes/src/components/ErrorReporting/ErrorReporting.tsx rename to plugins/kubernetes-react/src/components/ErrorReporting/ErrorReporting.tsx index 367e791067..64345662ed 100644 --- a/plugins/kubernetes/src/components/ErrorReporting/ErrorReporting.tsx +++ b/plugins/kubernetes-react/src/components/ErrorReporting/ErrorReporting.tsx @@ -14,10 +14,18 @@ * limitations under the License. */ import * as React from 'react'; -import { DetectedError, DetectedErrorsByCluster } from '../../error-detection'; +import { + DetectedError, + DetectedErrorsByCluster, +} from '@backstage/plugin-kubernetes-common'; import { Table, TableColumn } from '@backstage/core-components'; -type ErrorReportingProps = { +/** + * + * + * @public + */ +export type ErrorReportingProps = { detectedErrors: DetectedErrorsByCluster; }; @@ -65,6 +73,11 @@ const sortBySeverity = (a: Row, b: Row) => { return 0; }; +/** + * + * + * @public + */ export const ErrorReporting = ({ detectedErrors }: ErrorReportingProps) => { const errors = Array.from(detectedErrors.entries()) .flatMap(([clusterName, resourceErrors]) => { diff --git a/plugins/kubernetes-react/src/components/ErrorReporting/index.ts b/plugins/kubernetes-react/src/components/ErrorReporting/index.ts new file mode 100644 index 0000000000..3382849229 --- /dev/null +++ b/plugins/kubernetes-react/src/components/ErrorReporting/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2020 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 './ErrorReporting'; diff --git a/plugins/kubernetes/src/components/HorizontalPodAutoscalers/HorizontalPodAutoscalerDrawer.test.tsx b/plugins/kubernetes-react/src/components/HorizontalPodAutoscalers/HorizontalPodAutoscalerDrawer.test.tsx similarity index 100% rename from plugins/kubernetes/src/components/HorizontalPodAutoscalers/HorizontalPodAutoscalerDrawer.test.tsx rename to plugins/kubernetes-react/src/components/HorizontalPodAutoscalers/HorizontalPodAutoscalerDrawer.test.tsx diff --git a/plugins/kubernetes/src/components/HorizontalPodAutoscalers/HorizontalPodAutoscalerDrawer.tsx b/plugins/kubernetes-react/src/components/HorizontalPodAutoscalers/HorizontalPodAutoscalerDrawer.tsx similarity index 100% rename from plugins/kubernetes/src/components/HorizontalPodAutoscalers/HorizontalPodAutoscalerDrawer.tsx rename to plugins/kubernetes-react/src/components/HorizontalPodAutoscalers/HorizontalPodAutoscalerDrawer.tsx diff --git a/plugins/kubernetes/src/components/HorizontalPodAutoscalers/__fixtures__/horizontalpodautoscalers.json b/plugins/kubernetes-react/src/components/HorizontalPodAutoscalers/__fixtures__/horizontalpodautoscalers.json similarity index 100% rename from plugins/kubernetes/src/components/HorizontalPodAutoscalers/__fixtures__/horizontalpodautoscalers.json rename to plugins/kubernetes-react/src/components/HorizontalPodAutoscalers/__fixtures__/horizontalpodautoscalers.json diff --git a/plugins/kubernetes/src/components/HorizontalPodAutoscalers/index.ts b/plugins/kubernetes-react/src/components/HorizontalPodAutoscalers/index.ts similarity index 100% rename from plugins/kubernetes/src/components/HorizontalPodAutoscalers/index.ts rename to plugins/kubernetes-react/src/components/HorizontalPodAutoscalers/index.ts diff --git a/plugins/kubernetes/src/components/IngressesAccordions/IngressDrawer.test.tsx b/plugins/kubernetes-react/src/components/IngressesAccordions/IngressDrawer.test.tsx similarity index 100% rename from plugins/kubernetes/src/components/IngressesAccordions/IngressDrawer.test.tsx rename to plugins/kubernetes-react/src/components/IngressesAccordions/IngressDrawer.test.tsx diff --git a/plugins/kubernetes/src/components/IngressesAccordions/IngressDrawer.tsx b/plugins/kubernetes-react/src/components/IngressesAccordions/IngressDrawer.tsx similarity index 100% rename from plugins/kubernetes/src/components/IngressesAccordions/IngressDrawer.tsx rename to plugins/kubernetes-react/src/components/IngressesAccordions/IngressDrawer.tsx diff --git a/plugins/kubernetes/src/components/IngressesAccordions/IngressesAccordions.test.tsx b/plugins/kubernetes-react/src/components/IngressesAccordions/IngressesAccordions.test.tsx similarity index 100% rename from plugins/kubernetes/src/components/IngressesAccordions/IngressesAccordions.test.tsx rename to plugins/kubernetes-react/src/components/IngressesAccordions/IngressesAccordions.test.tsx diff --git a/plugins/kubernetes/src/components/IngressesAccordions/IngressesAccordions.tsx b/plugins/kubernetes-react/src/components/IngressesAccordions/IngressesAccordions.tsx similarity index 96% rename from plugins/kubernetes/src/components/IngressesAccordions/IngressesAccordions.tsx rename to plugins/kubernetes-react/src/components/IngressesAccordions/IngressesAccordions.tsx index 6e12c033ba..28aa5d42e4 100644 --- a/plugins/kubernetes/src/components/IngressesAccordions/IngressesAccordions.tsx +++ b/plugins/kubernetes-react/src/components/IngressesAccordions/IngressesAccordions.tsx @@ -27,7 +27,12 @@ import { IngressDrawer } from './IngressDrawer'; import { GroupedResponsesContext } from '../../hooks'; import { StructuredMetadataTable } from '@backstage/core-components'; -type IngressesAccordionsProps = {}; +/** + * + * + * @public + */ +export type IngressesAccordionsProps = {}; type IngressAccordionProps = { ingress: V1Ingress; @@ -78,6 +83,12 @@ const IngressAccordion = ({ ingress }: IngressAccordionProps) => { ); }; + +/** + * + * + * @public + */ export const IngressesAccordions = ({}: IngressesAccordionsProps) => { const groupedResponses = useContext(GroupedResponsesContext); return ( diff --git a/plugins/kubernetes/src/components/IngressesAccordions/__fixtures__/2-ingresses.json b/plugins/kubernetes-react/src/components/IngressesAccordions/__fixtures__/2-ingresses.json similarity index 100% rename from plugins/kubernetes/src/components/IngressesAccordions/__fixtures__/2-ingresses.json rename to plugins/kubernetes-react/src/components/IngressesAccordions/__fixtures__/2-ingresses.json diff --git a/plugins/kubernetes-react/src/components/IngressesAccordions/index.ts b/plugins/kubernetes-react/src/components/IngressesAccordions/index.ts new file mode 100644 index 0000000000..ece35ab17a --- /dev/null +++ b/plugins/kubernetes-react/src/components/IngressesAccordions/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2020 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 './IngressesAccordions'; diff --git a/plugins/kubernetes/src/components/JobsAccordions/JobsAccordions.test.tsx b/plugins/kubernetes-react/src/components/JobsAccordions/JobsAccordions.test.tsx similarity index 100% rename from plugins/kubernetes/src/components/JobsAccordions/JobsAccordions.test.tsx rename to plugins/kubernetes-react/src/components/JobsAccordions/JobsAccordions.test.tsx diff --git a/plugins/kubernetes/src/components/JobsAccordions/JobsAccordions.tsx b/plugins/kubernetes-react/src/components/JobsAccordions/JobsAccordions.tsx similarity index 97% rename from plugins/kubernetes/src/components/JobsAccordions/JobsAccordions.tsx rename to plugins/kubernetes-react/src/components/JobsAccordions/JobsAccordions.tsx index e805e3664b..460d0b80c0 100644 --- a/plugins/kubernetes/src/components/JobsAccordions/JobsAccordions.tsx +++ b/plugins/kubernetes-react/src/components/JobsAccordions/JobsAccordions.tsx @@ -32,7 +32,12 @@ import { StatusPending, } from '@backstage/core-components'; -type JobsAccordionsProps = { +/** + * + * + * @public + */ +export type JobsAccordionsProps = { jobs: V1Job[]; children?: React.ReactNode; }; @@ -98,6 +103,11 @@ const JobAccordion = ({ job, ownedPods }: JobAccordionProps) => { ); }; +/** + * + * + * @public + */ export const JobsAccordions = ({ jobs }: JobsAccordionsProps) => { const groupedResponses = useContext(GroupedResponsesContext); diff --git a/plugins/kubernetes/src/components/JobsAccordions/JobsDrawer.test.tsx b/plugins/kubernetes-react/src/components/JobsAccordions/JobsDrawer.test.tsx similarity index 100% rename from plugins/kubernetes/src/components/JobsAccordions/JobsDrawer.test.tsx rename to plugins/kubernetes-react/src/components/JobsAccordions/JobsDrawer.test.tsx diff --git a/plugins/kubernetes/src/components/JobsAccordions/JobsDrawer.tsx b/plugins/kubernetes-react/src/components/JobsAccordions/JobsDrawer.tsx similarity index 100% rename from plugins/kubernetes/src/components/JobsAccordions/JobsDrawer.tsx rename to plugins/kubernetes-react/src/components/JobsAccordions/JobsDrawer.tsx diff --git a/plugins/kubernetes/src/components/CronJobsAccordions/index.ts b/plugins/kubernetes-react/src/components/JobsAccordions/index.ts similarity index 91% rename from plugins/kubernetes/src/components/CronJobsAccordions/index.ts rename to plugins/kubernetes-react/src/components/JobsAccordions/index.ts index e72e3f7e6d..c69c493dc8 100644 --- a/plugins/kubernetes/src/components/CronJobsAccordions/index.ts +++ b/plugins/kubernetes-react/src/components/JobsAccordions/index.ts @@ -13,4 +13,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export { CronJobsAccordions } from './CronJobsAccordions'; +export * from './JobsAccordions'; diff --git a/plugins/kubernetes/src/components/KubernetesDrawer/KubernetesDrawer.tsx b/plugins/kubernetes-react/src/components/KubernetesDrawer/KubernetesDrawer.tsx similarity index 93% rename from plugins/kubernetes/src/components/KubernetesDrawer/KubernetesDrawer.tsx rename to plugins/kubernetes-react/src/components/KubernetesDrawer/KubernetesDrawer.tsx index 18ef5d9505..598dac4fe8 100644 --- a/plugins/kubernetes/src/components/KubernetesDrawer/KubernetesDrawer.tsx +++ b/plugins/kubernetes-react/src/components/KubernetesDrawer/KubernetesDrawer.tsx @@ -48,7 +48,12 @@ const useDrawerContentStyles = makeStyles((_theme: Theme) => }), ); -interface KubernetesObject { +/** + * The type of object that can be represented by the Drawer + * + * @public + */ +export interface KubernetesObject { kind: string; metadata?: IObjectMeta; } @@ -60,7 +65,7 @@ interface KubernetesDrawerContentProps { children?: React.ReactNode; } -export const KubernetesDrawerContent = ({ +const KubernetesDrawerContent = ({ children, header, kubernetesObject, @@ -115,7 +120,12 @@ export const KubernetesDrawerContent = ({ ); }; -interface KubernetesDrawerProps { +/** + * Props of KubernetesDrawer + * + * @public + */ +export interface KubernetesDrawerProps { open?: boolean; kubernetesObject: KubernetesObject; label: React.ReactNode; @@ -142,6 +152,11 @@ const DrawerButton = withStyles({ }, })(Button); +/** + * Button/Drawer component for Kubernetes Objects + * + * @public + */ export const KubernetesDrawer = ({ open, label, diff --git a/plugins/kubernetes/src/components/KubernetesDrawer/KubernetesStructuredMetadataTableDrawer.tsx b/plugins/kubernetes-react/src/components/KubernetesDrawer/KubernetesStructuredMetadataTableDrawer.tsx similarity index 95% rename from plugins/kubernetes/src/components/KubernetesDrawer/KubernetesStructuredMetadataTableDrawer.tsx rename to plugins/kubernetes-react/src/components/KubernetesDrawer/KubernetesStructuredMetadataTableDrawer.tsx index 8f28549f83..65001c658e 100644 --- a/plugins/kubernetes/src/components/KubernetesDrawer/KubernetesStructuredMetadataTableDrawer.tsx +++ b/plugins/kubernetes-react/src/components/KubernetesDrawer/KubernetesStructuredMetadataTableDrawer.tsx @@ -86,13 +86,26 @@ const PodDrawerButton = withStyles({ }, })(Button); -type ErrorPanelProps = { +/** + * + * + * @public + */ +export type LinkErrorPanelProps = { cluster: ClusterAttributes; errorMessage?: string; children?: React.ReactNode; }; -export const LinkErrorPanel = ({ cluster, errorMessage }: ErrorPanelProps) => ( +/** + * + * + * @public + */ +export const LinkErrorPanel = ({ + cluster, + errorMessage, +}: LinkErrorPanelProps) => ( ( ); -interface KubernetesDrawerable { +/** + * + * + * @public + */ +export interface KubernetesDrawerable { metadata?: V1ObjectMeta; } @@ -234,7 +252,12 @@ const KubernetesStructuredMetadataTableDrawerContent = < ); }; -interface KubernetesStructuredMetadataTableDrawerProps< + +/** + * + * @public + */ +export interface KubernetesStructuredMetadataTableDrawerProps< T extends KubernetesDrawerable, > { object: T; @@ -245,6 +268,10 @@ interface KubernetesStructuredMetadataTableDrawerProps< children?: React.ReactNode; } +/** + * + * @public + */ export const KubernetesStructuredMetadataTableDrawer = < T extends KubernetesDrawerable, >({ diff --git a/plugins/kubernetes/src/components/KubernetesDrawer/ManifestYaml.tsx b/plugins/kubernetes-react/src/components/KubernetesDrawer/ManifestYaml.tsx similarity index 94% rename from plugins/kubernetes/src/components/KubernetesDrawer/ManifestYaml.tsx rename to plugins/kubernetes-react/src/components/KubernetesDrawer/ManifestYaml.tsx index 8f0c38afde..246477b53b 100644 --- a/plugins/kubernetes/src/components/KubernetesDrawer/ManifestYaml.tsx +++ b/plugins/kubernetes-react/src/components/KubernetesDrawer/ManifestYaml.tsx @@ -18,10 +18,20 @@ import { FormControlLabel, Switch } from '@material-ui/core'; import jsyaml from 'js-yaml'; import React, { useState } from 'react'; +/** + * Props of ManifestYaml + * + * @public + */ export interface ManifestYamlProps { object: object; } +/** + * Renders a Kubernetes object as a YAML code snippet + * + * @public + */ export const ManifestYaml = ({ object }: ManifestYamlProps) => { // Toggle whether the Kubernetes resource managed fields should be shown in // the YAML display. This toggle is only available when the YAML is being diff --git a/plugins/kubernetes/src/components/KubernetesDrawer/index.ts b/plugins/kubernetes-react/src/components/KubernetesDrawer/index.ts similarity index 95% rename from plugins/kubernetes/src/components/KubernetesDrawer/index.ts rename to plugins/kubernetes-react/src/components/KubernetesDrawer/index.ts index a0108cbda6..cc5337544b 100644 --- a/plugins/kubernetes/src/components/KubernetesDrawer/index.ts +++ b/plugins/kubernetes-react/src/components/KubernetesDrawer/index.ts @@ -16,3 +16,4 @@ export * from './KubernetesStructuredMetadataTableDrawer'; export * from './KubernetesDrawer'; +export * from './ManifestYaml'; diff --git a/plugins/kubernetes/src/components/PodExecTerminal/PodExecTerminal.test.tsx b/plugins/kubernetes-react/src/components/PodExecTerminal/PodExecTerminal.test.tsx similarity index 100% rename from plugins/kubernetes/src/components/PodExecTerminal/PodExecTerminal.test.tsx rename to plugins/kubernetes-react/src/components/PodExecTerminal/PodExecTerminal.test.tsx diff --git a/plugins/kubernetes/src/components/PodExecTerminal/PodExecTerminal.tsx b/plugins/kubernetes-react/src/components/PodExecTerminal/PodExecTerminal.tsx similarity index 99% rename from plugins/kubernetes/src/components/PodExecTerminal/PodExecTerminal.tsx rename to plugins/kubernetes-react/src/components/PodExecTerminal/PodExecTerminal.tsx index a741f4e189..f8106bd011 100644 --- a/plugins/kubernetes/src/components/PodExecTerminal/PodExecTerminal.tsx +++ b/plugins/kubernetes-react/src/components/PodExecTerminal/PodExecTerminal.tsx @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import 'xterm/css/xterm.css'; +import 'xterm'; import { discoveryApiRef, useApi } from '@backstage/core-plugin-api'; import React, { useEffect, useMemo, useState } from 'react'; diff --git a/plugins/kubernetes/src/components/PodExecTerminal/PodExecTerminalAttachAddon.ts b/plugins/kubernetes-react/src/components/PodExecTerminal/PodExecTerminalAttachAddon.ts similarity index 100% rename from plugins/kubernetes/src/components/PodExecTerminal/PodExecTerminalAttachAddon.ts rename to plugins/kubernetes-react/src/components/PodExecTerminal/PodExecTerminalAttachAddon.ts diff --git a/plugins/kubernetes/src/components/PodExecTerminal/PodExecTerminalDialog.tsx b/plugins/kubernetes-react/src/components/PodExecTerminal/PodExecTerminalDialog.tsx similarity index 100% rename from plugins/kubernetes/src/components/PodExecTerminal/PodExecTerminalDialog.tsx rename to plugins/kubernetes-react/src/components/PodExecTerminal/PodExecTerminalDialog.tsx diff --git a/plugins/kubernetes/src/components/PodExecTerminal/index.ts b/plugins/kubernetes-react/src/components/PodExecTerminal/index.ts similarity index 100% rename from plugins/kubernetes/src/components/PodExecTerminal/index.ts rename to plugins/kubernetes-react/src/components/PodExecTerminal/index.ts diff --git a/plugins/kubernetes/src/components/PodExecTerminal/matchMedia.mock.ts b/plugins/kubernetes-react/src/components/PodExecTerminal/matchMedia.mock.ts similarity index 100% rename from plugins/kubernetes/src/components/PodExecTerminal/matchMedia.mock.ts rename to plugins/kubernetes-react/src/components/PodExecTerminal/matchMedia.mock.ts diff --git a/plugins/kubernetes/src/components/Pods/ErrorList/ErrorList.test.tsx b/plugins/kubernetes-react/src/components/Pods/ErrorList/ErrorList.test.tsx similarity index 97% rename from plugins/kubernetes/src/components/Pods/ErrorList/ErrorList.test.tsx rename to plugins/kubernetes-react/src/components/Pods/ErrorList/ErrorList.test.tsx index b05b4d2d9e..2423654cc3 100644 --- a/plugins/kubernetes/src/components/Pods/ErrorList/ErrorList.test.tsx +++ b/plugins/kubernetes-react/src/components/Pods/ErrorList/ErrorList.test.tsx @@ -18,7 +18,7 @@ import React from 'react'; import { render } from '@testing-library/react'; import { ErrorList } from './ErrorList'; -import { Pod } from 'kubernetes-models/v1/Pod'; +import { Pod } from 'kubernetes-models/v1'; describe('ErrorList', () => { it('error highlight should render', () => { diff --git a/plugins/kubernetes/src/components/Pods/ErrorList/ErrorList.tsx b/plugins/kubernetes-react/src/components/Pods/ErrorList/ErrorList.tsx similarity index 100% rename from plugins/kubernetes/src/components/Pods/ErrorList/ErrorList.tsx rename to plugins/kubernetes-react/src/components/Pods/ErrorList/ErrorList.tsx diff --git a/plugins/kubernetes/src/components/Pods/ErrorList/index.ts b/plugins/kubernetes-react/src/components/Pods/ErrorList/index.ts similarity index 100% rename from plugins/kubernetes/src/components/Pods/ErrorList/index.ts rename to plugins/kubernetes-react/src/components/Pods/ErrorList/index.ts diff --git a/plugins/kubernetes/src/components/Pods/Events/Events.test.tsx b/plugins/kubernetes-react/src/components/Pods/Events/Events.test.tsx similarity index 100% rename from plugins/kubernetes/src/components/Pods/Events/Events.test.tsx rename to plugins/kubernetes-react/src/components/Pods/Events/Events.test.tsx diff --git a/plugins/kubernetes/src/components/Pods/Events/Events.tsx b/plugins/kubernetes-react/src/components/Pods/Events/Events.tsx similarity index 100% rename from plugins/kubernetes/src/components/Pods/Events/Events.tsx rename to plugins/kubernetes-react/src/components/Pods/Events/Events.tsx diff --git a/plugins/kubernetes/src/components/Pods/Events/index.ts b/plugins/kubernetes-react/src/components/Pods/Events/index.ts similarity index 100% rename from plugins/kubernetes/src/components/Pods/Events/index.ts rename to plugins/kubernetes-react/src/components/Pods/Events/index.ts diff --git a/plugins/kubernetes/src/components/Pods/Events/useEvents.test.tsx b/plugins/kubernetes-react/src/components/Pods/Events/useEvents.test.tsx similarity index 100% rename from plugins/kubernetes/src/components/Pods/Events/useEvents.test.tsx rename to plugins/kubernetes-react/src/components/Pods/Events/useEvents.test.tsx diff --git a/plugins/kubernetes/src/components/Pods/Events/useEvents.ts b/plugins/kubernetes-react/src/components/Pods/Events/useEvents.ts similarity index 95% rename from plugins/kubernetes/src/components/Pods/Events/useEvents.ts rename to plugins/kubernetes-react/src/components/Pods/Events/useEvents.ts index 441937507d..e31a4ee859 100644 --- a/plugins/kubernetes/src/components/Pods/Events/useEvents.ts +++ b/plugins/kubernetes-react/src/components/Pods/Events/useEvents.ts @@ -15,7 +15,7 @@ */ import { useApi } from '@backstage/core-plugin-api'; import useAsync from 'react-use/lib/useAsync'; -import { kubernetesProxyApiRef } from '../../../api'; +import { kubernetesProxyApiRef } from '../../../api/types'; /** * Arguments for useEvents diff --git a/plugins/kubernetes/src/components/Pods/FixDialog/FixDialog.test.tsx b/plugins/kubernetes-react/src/components/Pods/FixDialog/FixDialog.test.tsx similarity index 100% rename from plugins/kubernetes/src/components/Pods/FixDialog/FixDialog.test.tsx rename to plugins/kubernetes-react/src/components/Pods/FixDialog/FixDialog.test.tsx diff --git a/plugins/kubernetes/src/components/Pods/FixDialog/FixDialog.tsx b/plugins/kubernetes-react/src/components/Pods/FixDialog/FixDialog.tsx similarity index 98% rename from plugins/kubernetes/src/components/Pods/FixDialog/FixDialog.tsx rename to plugins/kubernetes-react/src/components/Pods/FixDialog/FixDialog.tsx index 63ce4af03b..c691cc67fd 100644 --- a/plugins/kubernetes/src/components/Pods/FixDialog/FixDialog.tsx +++ b/plugins/kubernetes-react/src/components/Pods/FixDialog/FixDialog.tsx @@ -28,7 +28,7 @@ import HelpIcon from '@material-ui/icons/Help'; import OpenInNewIcon from '@material-ui/icons/OpenInNew'; import { Pod } from 'kubernetes-models/v1/Pod'; -import { DetectedError } from '../../../error-detection'; +import { DetectedError } from '@backstage/plugin-kubernetes-common'; import { PodLogs } from '../PodLogs'; import { Events } from '../Events'; import { LinkButton } from '@backstage/core-components'; diff --git a/plugins/kubernetes/src/components/Pods/FixDialog/index.ts b/plugins/kubernetes-react/src/components/Pods/FixDialog/index.ts similarity index 100% rename from plugins/kubernetes/src/components/Pods/FixDialog/index.ts rename to plugins/kubernetes-react/src/components/Pods/FixDialog/index.ts diff --git a/plugins/kubernetes/src/components/Pods/PodDrawer/ContainerCard.test.tsx b/plugins/kubernetes-react/src/components/Pods/PodDrawer/ContainerCard.test.tsx similarity index 100% rename from plugins/kubernetes/src/components/Pods/PodDrawer/ContainerCard.test.tsx rename to plugins/kubernetes-react/src/components/Pods/PodDrawer/ContainerCard.test.tsx diff --git a/plugins/kubernetes/src/components/Pods/PodDrawer/ContainerCard.tsx b/plugins/kubernetes-react/src/components/Pods/PodDrawer/ContainerCard.tsx similarity index 100% rename from plugins/kubernetes/src/components/Pods/PodDrawer/ContainerCard.tsx rename to plugins/kubernetes-react/src/components/Pods/PodDrawer/ContainerCard.tsx diff --git a/plugins/kubernetes/src/components/Pods/PodDrawer/PendingPodContent.test.tsx b/plugins/kubernetes-react/src/components/Pods/PodDrawer/PendingPodContent.test.tsx similarity index 100% rename from plugins/kubernetes/src/components/Pods/PodDrawer/PendingPodContent.test.tsx rename to plugins/kubernetes-react/src/components/Pods/PodDrawer/PendingPodContent.test.tsx diff --git a/plugins/kubernetes/src/components/Pods/PodDrawer/PendingPodContent.tsx b/plugins/kubernetes-react/src/components/Pods/PodDrawer/PendingPodContent.tsx similarity index 100% rename from plugins/kubernetes/src/components/Pods/PodDrawer/PendingPodContent.tsx rename to plugins/kubernetes-react/src/components/Pods/PodDrawer/PendingPodContent.tsx diff --git a/plugins/kubernetes/src/components/Pods/PodDrawer/PodDrawer.test.tsx b/plugins/kubernetes-react/src/components/Pods/PodDrawer/PodDrawer.test.tsx similarity index 100% rename from plugins/kubernetes/src/components/Pods/PodDrawer/PodDrawer.test.tsx rename to plugins/kubernetes-react/src/components/Pods/PodDrawer/PodDrawer.test.tsx diff --git a/plugins/kubernetes/src/components/Pods/PodDrawer/PodDrawer.tsx b/plugins/kubernetes-react/src/components/Pods/PodDrawer/PodDrawer.tsx similarity index 99% rename from plugins/kubernetes/src/components/Pods/PodDrawer/PodDrawer.tsx rename to plugins/kubernetes-react/src/components/Pods/PodDrawer/PodDrawer.tsx index 30588cd347..1b98237d5a 100644 --- a/plugins/kubernetes/src/components/Pods/PodDrawer/PodDrawer.tsx +++ b/plugins/kubernetes-react/src/components/Pods/PodDrawer/PodDrawer.tsx @@ -67,7 +67,7 @@ function getContainerSpecByName(pod: Pod, containerName: string) { * * @public */ -interface PodDrawerProps { +export interface PodDrawerProps { open?: boolean; podAndErrors: PodAndErrors; } diff --git a/plugins/kubernetes/src/components/Pods/PodDrawer/index.ts b/plugins/kubernetes-react/src/components/Pods/PodDrawer/index.ts similarity index 100% rename from plugins/kubernetes/src/components/Pods/PodDrawer/index.ts rename to plugins/kubernetes-react/src/components/Pods/PodDrawer/index.ts diff --git a/plugins/kubernetes/src/components/Pods/PodLogs/PodLogs.tsx b/plugins/kubernetes-react/src/components/Pods/PodLogs/PodLogs.tsx similarity index 100% rename from plugins/kubernetes/src/components/Pods/PodLogs/PodLogs.tsx rename to plugins/kubernetes-react/src/components/Pods/PodLogs/PodLogs.tsx diff --git a/plugins/kubernetes/src/components/Pods/PodLogs/PodLogsDialog.tsx b/plugins/kubernetes-react/src/components/Pods/PodLogs/PodLogsDialog.tsx similarity index 100% rename from plugins/kubernetes/src/components/Pods/PodLogs/PodLogsDialog.tsx rename to plugins/kubernetes-react/src/components/Pods/PodLogs/PodLogsDialog.tsx diff --git a/plugins/kubernetes/src/components/Pods/PodLogs/index.ts b/plugins/kubernetes-react/src/components/Pods/PodLogs/index.ts similarity index 100% rename from plugins/kubernetes/src/components/Pods/PodLogs/index.ts rename to plugins/kubernetes-react/src/components/Pods/PodLogs/index.ts diff --git a/plugins/kubernetes/src/components/Pods/PodLogs/types.ts b/plugins/kubernetes-react/src/components/Pods/PodLogs/types.ts similarity index 100% rename from plugins/kubernetes/src/components/Pods/PodLogs/types.ts rename to plugins/kubernetes-react/src/components/Pods/PodLogs/types.ts diff --git a/plugins/kubernetes/src/components/Pods/PodLogs/usePodLogs.ts b/plugins/kubernetes-react/src/components/Pods/PodLogs/usePodLogs.ts similarity index 95% rename from plugins/kubernetes/src/components/Pods/PodLogs/usePodLogs.ts rename to plugins/kubernetes-react/src/components/Pods/PodLogs/usePodLogs.ts index 495bb1dc71..26764fc64c 100644 --- a/plugins/kubernetes/src/components/Pods/PodLogs/usePodLogs.ts +++ b/plugins/kubernetes-react/src/components/Pods/PodLogs/usePodLogs.ts @@ -17,7 +17,7 @@ import useAsync from 'react-use/lib/useAsync'; import { ContainerScope } from './types'; import { useApi } from '@backstage/core-plugin-api'; -import { kubernetesProxyApiRef } from '../../../api'; +import { kubernetesProxyApiRef } from '../../../api/types'; /** * Arguments for usePodLogs diff --git a/plugins/kubernetes/src/components/Pods/PodsTable.test.tsx b/plugins/kubernetes-react/src/components/Pods/PodsTable.test.tsx similarity index 100% rename from plugins/kubernetes/src/components/Pods/PodsTable.test.tsx rename to plugins/kubernetes-react/src/components/Pods/PodsTable.test.tsx diff --git a/plugins/kubernetes/src/components/Pods/PodsTable.tsx b/plugins/kubernetes-react/src/components/Pods/PodsTable.tsx similarity index 96% rename from plugins/kubernetes/src/components/Pods/PodsTable.tsx rename to plugins/kubernetes-react/src/components/Pods/PodsTable.tsx index bebfbd0b5d..f7c2660c84 100644 --- a/plugins/kubernetes/src/components/Pods/PodsTable.tsx +++ b/plugins/kubernetes-react/src/components/Pods/PodsTable.tsx @@ -31,11 +31,33 @@ import { V1Pod } from '@kubernetes/client-node'; import { usePodMetrics } from '../../hooks/usePodMetrics'; import { Typography } from '@material-ui/core'; +/** + * + * + * @public + */ export const READY_COLUMNS: PodColumns = 'READY'; + +/** + * + * + * @public + */ export const RESOURCE_COLUMNS: PodColumns = 'RESOURCE'; + +/** + * + * + * @public + */ export type PodColumns = 'READY' | 'RESOURCE'; -type PodsTablesProps = { +/** + * + * + * @public + */ +export type PodsTablesProps = { pods: Pod | V1Pod[]; extraColumns?: PodColumns[]; children?: React.ReactNode; @@ -95,6 +117,11 @@ const Memory = ({ clusterName, pod }: { clusterName: string; pod: Pod }) => { return <>{podStatusToMemoryUtil(metrics)}; }; +/** + * + * + * @public + */ export const PodsTable = ({ pods, extraColumns = [] }: PodsTablesProps) => { const cluster = useContext(ClusterContext); const defaultColumns: TableColumn[] = [ diff --git a/plugins/kubernetes/src/components/Pods/__fixtures__/crashing-pod.json b/plugins/kubernetes-react/src/components/Pods/__fixtures__/crashing-pod.json similarity index 100% rename from plugins/kubernetes/src/components/Pods/__fixtures__/crashing-pod.json rename to plugins/kubernetes-react/src/components/Pods/__fixtures__/crashing-pod.json diff --git a/plugins/kubernetes/src/error-detection/__fixtures__/pod.json b/plugins/kubernetes-react/src/components/Pods/__fixtures__/pod.json similarity index 100% rename from plugins/kubernetes/src/error-detection/__fixtures__/pod.json rename to plugins/kubernetes-react/src/components/Pods/__fixtures__/pod.json diff --git a/plugins/kubernetes/src/components/Pods/index.ts b/plugins/kubernetes-react/src/components/Pods/index.ts similarity index 94% rename from plugins/kubernetes/src/components/Pods/index.ts rename to plugins/kubernetes-react/src/components/Pods/index.ts index c4282de53a..6297a0abce 100644 --- a/plugins/kubernetes/src/components/Pods/index.ts +++ b/plugins/kubernetes-react/src/components/Pods/index.ts @@ -18,5 +18,5 @@ export * from './PodLogs'; export * from './FixDialog'; export * from './Events'; export * from './ErrorList'; -export { PodsTable } from './PodsTable'; +export * from './PodsTable'; export * from './types'; diff --git a/plugins/kubernetes/src/components/Pods/types.ts b/plugins/kubernetes-react/src/components/Pods/types.ts similarity index 92% rename from plugins/kubernetes/src/components/Pods/types.ts rename to plugins/kubernetes-react/src/components/Pods/types.ts index 877df39c24..847e6d63bc 100644 --- a/plugins/kubernetes/src/components/Pods/types.ts +++ b/plugins/kubernetes-react/src/components/Pods/types.ts @@ -14,7 +14,7 @@ * limitations under the License. */ import { Pod } from 'kubernetes-models/v1'; -import { DetectedError } from '../../error-detection'; +import { DetectedError } from '@backstage/plugin-kubernetes-common'; /** * Wraps a pod with the associated detected errors and cluster name diff --git a/plugins/kubernetes/src/components/ResourceUtilization/ResourceUtilization.test.tsx b/plugins/kubernetes-react/src/components/ResourceUtilization/ResourceUtilization.test.tsx similarity index 100% rename from plugins/kubernetes/src/components/ResourceUtilization/ResourceUtilization.test.tsx rename to plugins/kubernetes-react/src/components/ResourceUtilization/ResourceUtilization.test.tsx diff --git a/plugins/kubernetes/src/components/ResourceUtilization/ResourceUtilization.tsx b/plugins/kubernetes-react/src/components/ResourceUtilization/ResourceUtilization.tsx similarity index 96% rename from plugins/kubernetes/src/components/ResourceUtilization/ResourceUtilization.tsx rename to plugins/kubernetes-react/src/components/ResourceUtilization/ResourceUtilization.tsx index 75927958e6..15f906e469 100644 --- a/plugins/kubernetes/src/components/ResourceUtilization/ResourceUtilization.tsx +++ b/plugins/kubernetes-react/src/components/ResourceUtilization/ResourceUtilization.tsx @@ -32,8 +32,7 @@ export interface ResourceUtilizationProps { totalFormatted: string; } -// Visible for testing -export const getProgressColor: GaugePropsGetColor = ({ +const getProgressColor: GaugePropsGetColor = ({ palette, value, inverse, diff --git a/plugins/kubernetes/src/components/ResourceUtilization/index.ts b/plugins/kubernetes-react/src/components/ResourceUtilization/index.ts similarity index 90% rename from plugins/kubernetes/src/components/ResourceUtilization/index.ts rename to plugins/kubernetes-react/src/components/ResourceUtilization/index.ts index 33d232cbf4..088d78a40b 100644 --- a/plugins/kubernetes/src/components/ResourceUtilization/index.ts +++ b/plugins/kubernetes-react/src/components/ResourceUtilization/index.ts @@ -13,4 +13,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export { ResourceUtilization } from './ResourceUtilization'; +export * from './ResourceUtilization'; diff --git a/plugins/kubernetes/src/components/ServicesAccordions/ServiceDrawer.test.tsx b/plugins/kubernetes-react/src/components/ServicesAccordions/ServiceDrawer.test.tsx similarity index 100% rename from plugins/kubernetes/src/components/ServicesAccordions/ServiceDrawer.test.tsx rename to plugins/kubernetes-react/src/components/ServicesAccordions/ServiceDrawer.test.tsx diff --git a/plugins/kubernetes/src/components/ServicesAccordions/ServiceDrawer.tsx b/plugins/kubernetes-react/src/components/ServicesAccordions/ServiceDrawer.tsx similarity index 100% rename from plugins/kubernetes/src/components/ServicesAccordions/ServiceDrawer.tsx rename to plugins/kubernetes-react/src/components/ServicesAccordions/ServiceDrawer.tsx diff --git a/plugins/kubernetes/src/components/ServicesAccordions/ServicesAccordions.test.tsx b/plugins/kubernetes-react/src/components/ServicesAccordions/ServicesAccordions.test.tsx similarity index 100% rename from plugins/kubernetes/src/components/ServicesAccordions/ServicesAccordions.test.tsx rename to plugins/kubernetes-react/src/components/ServicesAccordions/ServicesAccordions.test.tsx diff --git a/plugins/kubernetes/src/components/ServicesAccordions/ServicesAccordions.tsx b/plugins/kubernetes-react/src/components/ServicesAccordions/ServicesAccordions.tsx similarity index 97% rename from plugins/kubernetes/src/components/ServicesAccordions/ServicesAccordions.tsx rename to plugins/kubernetes-react/src/components/ServicesAccordions/ServicesAccordions.tsx index f0cb99ec9c..50d6ec6f3e 100644 --- a/plugins/kubernetes/src/components/ServicesAccordions/ServicesAccordions.tsx +++ b/plugins/kubernetes-react/src/components/ServicesAccordions/ServicesAccordions.tsx @@ -83,7 +83,12 @@ const ServiceCard = ({ service }: ServiceCardProps) => { ); }; -type ServicesAccordionsProps = {}; +/** + * + * + * @public + */ +export type ServicesAccordionsProps = {}; type ServiceAccordionProps = { service: V1Service; @@ -102,6 +107,11 @@ const ServiceAccordion = ({ service }: ServiceAccordionProps) => { ); }; +/** + * + * + * @public + */ export const ServicesAccordions = ({}: ServicesAccordionsProps) => { const groupedResponses = useContext(GroupedResponsesContext); return ( diff --git a/plugins/kubernetes/src/components/ServicesAccordions/__fixtures__/2-services.json b/plugins/kubernetes-react/src/components/ServicesAccordions/__fixtures__/2-services.json similarity index 100% rename from plugins/kubernetes/src/components/ServicesAccordions/__fixtures__/2-services.json rename to plugins/kubernetes-react/src/components/ServicesAccordions/__fixtures__/2-services.json diff --git a/plugins/kubernetes-react/src/components/ServicesAccordions/index.ts b/plugins/kubernetes-react/src/components/ServicesAccordions/index.ts new file mode 100644 index 0000000000..db37d34b5f --- /dev/null +++ b/plugins/kubernetes-react/src/components/ServicesAccordions/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2020 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 './ServicesAccordions'; diff --git a/plugins/kubernetes/src/components/StatefulSetsAccordions/StatefulSetDrawer.test.tsx b/plugins/kubernetes-react/src/components/StatefulSetsAccordions/StatefulSetDrawer.test.tsx similarity index 100% rename from plugins/kubernetes/src/components/StatefulSetsAccordions/StatefulSetDrawer.test.tsx rename to plugins/kubernetes-react/src/components/StatefulSetsAccordions/StatefulSetDrawer.test.tsx diff --git a/plugins/kubernetes/src/components/StatefulSetsAccordions/StatefulSetDrawer.tsx b/plugins/kubernetes-react/src/components/StatefulSetsAccordions/StatefulSetDrawer.tsx similarity index 100% rename from plugins/kubernetes/src/components/StatefulSetsAccordions/StatefulSetDrawer.tsx rename to plugins/kubernetes-react/src/components/StatefulSetsAccordions/StatefulSetDrawer.tsx diff --git a/plugins/kubernetes/src/components/StatefulSetsAccordions/StatefulSetsAccordions.test.tsx b/plugins/kubernetes-react/src/components/StatefulSetsAccordions/StatefulSetsAccordions.test.tsx similarity index 100% rename from plugins/kubernetes/src/components/StatefulSetsAccordions/StatefulSetsAccordions.test.tsx rename to plugins/kubernetes-react/src/components/StatefulSetsAccordions/StatefulSetsAccordions.test.tsx diff --git a/plugins/kubernetes/src/components/StatefulSetsAccordions/StatefulSetsAccordions.tsx b/plugins/kubernetes-react/src/components/StatefulSetsAccordions/StatefulSetsAccordions.tsx similarity index 100% rename from plugins/kubernetes/src/components/StatefulSetsAccordions/StatefulSetsAccordions.tsx rename to plugins/kubernetes-react/src/components/StatefulSetsAccordions/StatefulSetsAccordions.tsx diff --git a/plugins/kubernetes/src/components/StatefulSetsAccordions/index.ts b/plugins/kubernetes-react/src/components/StatefulSetsAccordions/index.ts similarity index 100% rename from plugins/kubernetes/src/components/StatefulSetsAccordions/index.ts rename to plugins/kubernetes-react/src/components/StatefulSetsAccordions/index.ts diff --git a/plugins/kubernetes/src/components/index.ts b/plugins/kubernetes-react/src/components/index.ts similarity index 96% rename from plugins/kubernetes/src/components/index.ts rename to plugins/kubernetes-react/src/components/index.ts index 18b75247e5..d9cebe35a3 100644 --- a/plugins/kubernetes/src/components/index.ts +++ b/plugins/kubernetes-react/src/components/index.ts @@ -25,6 +25,5 @@ export * from './JobsAccordions'; export * from './KubernetesDrawer'; export * from './Pods'; export * from './ServicesAccordions'; -export * from './KubernetesContent'; export * from './ResourceUtilization'; export * from './PodExecTerminal'; diff --git a/plugins/kubernetes/src/hooks/Cluster.ts b/plugins/kubernetes-react/src/hooks/Cluster.ts similarity index 97% rename from plugins/kubernetes/src/hooks/Cluster.ts rename to plugins/kubernetes-react/src/hooks/Cluster.ts index e8d01c462c..ee950b7f4d 100644 --- a/plugins/kubernetes/src/hooks/Cluster.ts +++ b/plugins/kubernetes-react/src/hooks/Cluster.ts @@ -16,6 +16,9 @@ import React from 'react'; import { ClusterAttributes } from '@backstage/plugin-kubernetes-common'; +/** + * @public + */ export const ClusterContext = React.createContext({ name: '', }); diff --git a/plugins/kubernetes/src/hooks/GroupedResponses.ts b/plugins/kubernetes-react/src/hooks/GroupedResponses.ts similarity index 90% rename from plugins/kubernetes/src/hooks/GroupedResponses.ts rename to plugins/kubernetes-react/src/hooks/GroupedResponses.ts index 8383c9e1d9..7a81a74337 100644 --- a/plugins/kubernetes/src/hooks/GroupedResponses.ts +++ b/plugins/kubernetes-react/src/hooks/GroupedResponses.ts @@ -14,8 +14,13 @@ * limitations under the License. */ import React from 'react'; -import { GroupedResponses } from '../types/types'; +import { GroupedResponses } from '@backstage/plugin-kubernetes-common'; +/** + * + * + * @public + */ export const GroupedResponsesContext = React.createContext({ pods: [], replicaSets: [], diff --git a/plugins/kubernetes/src/hooks/PodNamesWithErrors.ts b/plugins/kubernetes-react/src/hooks/PodNamesWithErrors.ts similarity index 97% rename from plugins/kubernetes/src/hooks/PodNamesWithErrors.ts rename to plugins/kubernetes-react/src/hooks/PodNamesWithErrors.ts index 7505da3fd2..001a40805f 100644 --- a/plugins/kubernetes/src/hooks/PodNamesWithErrors.ts +++ b/plugins/kubernetes-react/src/hooks/PodNamesWithErrors.ts @@ -15,6 +15,9 @@ */ import React from 'react'; +/** + * @public + */ export const PodNamesWithErrorsContext = React.createContext>( new Set(), ); diff --git a/plugins/kubernetes/src/hooks/PodNamesWithMetrics.ts b/plugins/kubernetes-react/src/hooks/PodNamesWithMetrics.ts similarity index 97% rename from plugins/kubernetes/src/hooks/PodNamesWithMetrics.ts rename to plugins/kubernetes-react/src/hooks/PodNamesWithMetrics.ts index 0df42a8ab0..12da138cfb 100644 --- a/plugins/kubernetes/src/hooks/PodNamesWithMetrics.ts +++ b/plugins/kubernetes-react/src/hooks/PodNamesWithMetrics.ts @@ -16,8 +16,8 @@ import React from 'react'; import { ClientPodStatus } from '@backstage/plugin-kubernetes-common'; -/* - * @deprecated +/** + * @public */ export const PodNamesWithMetricsContext = React.createContext< Map diff --git a/plugins/kubernetes/src/hooks/__mocks__/useIsPodExecTerminalSupported.ts b/plugins/kubernetes-react/src/hooks/__mocks__/useIsPodExecTerminalSupported.ts similarity index 100% rename from plugins/kubernetes/src/hooks/__mocks__/useIsPodExecTerminalSupported.ts rename to plugins/kubernetes-react/src/hooks/__mocks__/useIsPodExecTerminalSupported.ts diff --git a/plugins/kubernetes/src/hooks/auth.test.ts b/plugins/kubernetes-react/src/hooks/auth.test.ts similarity index 100% rename from plugins/kubernetes/src/hooks/auth.test.ts rename to plugins/kubernetes-react/src/hooks/auth.test.ts diff --git a/plugins/kubernetes/src/hooks/auth.ts b/plugins/kubernetes-react/src/hooks/auth.ts similarity index 98% rename from plugins/kubernetes/src/hooks/auth.ts rename to plugins/kubernetes-react/src/hooks/auth.ts index cce0bc27d6..76e08f2783 100644 --- a/plugins/kubernetes/src/hooks/auth.ts +++ b/plugins/kubernetes-react/src/hooks/auth.ts @@ -15,9 +15,9 @@ */ import { Entity } from '@backstage/catalog-model'; -import { KubernetesApi } from '../api/types'; -import { KubernetesAuthProvidersApi } from '../kubernetes-auth-provider/types'; import { KubernetesRequestBody } from '@backstage/plugin-kubernetes-common'; +import { KubernetesAuthProvidersApi } from '../kubernetes-auth-provider'; +import { KubernetesApi } from '../api/types'; export const generateAuth = async ( entity: Entity, diff --git a/plugins/kubernetes/src/hooks/index.ts b/plugins/kubernetes-react/src/hooks/index.ts similarity index 100% rename from plugins/kubernetes/src/hooks/index.ts rename to plugins/kubernetes-react/src/hooks/index.ts diff --git a/plugins/kubernetes/src/hooks/test-utils.tsx b/plugins/kubernetes-react/src/hooks/test-utils.tsx similarity index 100% rename from plugins/kubernetes/src/hooks/test-utils.tsx rename to plugins/kubernetes-react/src/hooks/test-utils.tsx diff --git a/plugins/kubernetes/src/hooks/types.ts b/plugins/kubernetes-react/src/hooks/types.ts similarity index 100% rename from plugins/kubernetes/src/hooks/types.ts rename to plugins/kubernetes-react/src/hooks/types.ts diff --git a/plugins/kubernetes/src/hooks/useCustomResources.test.ts b/plugins/kubernetes-react/src/hooks/useCustomResources.test.ts similarity index 100% rename from plugins/kubernetes/src/hooks/useCustomResources.test.ts rename to plugins/kubernetes-react/src/hooks/useCustomResources.test.ts diff --git a/plugins/kubernetes/src/hooks/useCustomResources.ts b/plugins/kubernetes-react/src/hooks/useCustomResources.ts similarity index 99% rename from plugins/kubernetes/src/hooks/useCustomResources.ts rename to plugins/kubernetes-react/src/hooks/useCustomResources.ts index c53e00d81c..4faeb48894 100644 --- a/plugins/kubernetes/src/hooks/useCustomResources.ts +++ b/plugins/kubernetes-react/src/hooks/useCustomResources.ts @@ -15,8 +15,6 @@ */ import { Entity } from '@backstage/catalog-model'; -import { kubernetesApiRef } from '../api/types'; -import { kubernetesAuthProvidersApiRef } from '../kubernetes-auth-provider/types'; import { useCallback } from 'react'; import useInterval from 'react-use/lib/useInterval'; import { @@ -27,6 +25,8 @@ import { useApi } from '@backstage/core-plugin-api'; import { KubernetesObjects } from './useKubernetesObjects'; import { generateAuth } from './auth'; import useAsyncRetry from 'react-use/lib/useAsyncRetry'; +import { kubernetesAuthProvidersApiRef } from '../kubernetes-auth-provider'; +import { kubernetesApiRef } from '../api/types'; /** * Retrieves the provided custom resources related to the provided entity, refreshes at an interval. diff --git a/plugins/kubernetes/src/hooks/useIsPodExecTerminalSupported.test.ts b/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalSupported.test.ts similarity index 100% rename from plugins/kubernetes/src/hooks/useIsPodExecTerminalSupported.test.ts rename to plugins/kubernetes-react/src/hooks/useIsPodExecTerminalSupported.test.ts diff --git a/plugins/kubernetes/src/hooks/useIsPodExecTerminalSupported.ts b/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalSupported.ts similarity index 96% rename from plugins/kubernetes/src/hooks/useIsPodExecTerminalSupported.ts rename to plugins/kubernetes-react/src/hooks/useIsPodExecTerminalSupported.ts index 17f64bf0dd..e881951059 100644 --- a/plugins/kubernetes/src/hooks/useIsPodExecTerminalSupported.ts +++ b/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalSupported.ts @@ -15,8 +15,7 @@ */ import { useApi } from '@backstage/core-plugin-api'; import useAsync, { AsyncState } from 'react-use/lib/useAsync'; - -import { kubernetesApiRef } from '../api'; +import { kubernetesApiRef } from '../api/types'; /** * Check if conditions for a pod exec call through the proxy endpoint are met diff --git a/plugins/kubernetes/src/hooks/useKubernetesObjects.test.ts b/plugins/kubernetes-react/src/hooks/useKubernetesObjects.test.ts similarity index 100% rename from plugins/kubernetes/src/hooks/useKubernetesObjects.test.ts rename to plugins/kubernetes-react/src/hooks/useKubernetesObjects.test.ts diff --git a/plugins/kubernetes/src/hooks/useKubernetesObjects.ts b/plugins/kubernetes-react/src/hooks/useKubernetesObjects.ts similarity index 97% rename from plugins/kubernetes/src/hooks/useKubernetesObjects.ts rename to plugins/kubernetes-react/src/hooks/useKubernetesObjects.ts index aad2f48fd3..f2b8de3cc6 100644 --- a/plugins/kubernetes/src/hooks/useKubernetesObjects.ts +++ b/plugins/kubernetes-react/src/hooks/useKubernetesObjects.ts @@ -15,21 +15,29 @@ */ import { Entity } from '@backstage/catalog-model'; -import { kubernetesApiRef } from '../api/types'; -import { kubernetesAuthProvidersApiRef } from '../kubernetes-auth-provider/types'; import { useCallback } from 'react'; import useInterval from 'react-use/lib/useInterval'; import { ObjectsByEntityResponse } from '@backstage/plugin-kubernetes-common'; import { useApi } from '@backstage/core-plugin-api'; import { generateAuth } from './auth'; import useAsyncRetry from 'react-use/lib/useAsyncRetry'; +import { kubernetesAuthProvidersApiRef } from '../kubernetes-auth-provider'; +import { kubernetesApiRef } from '../api/types'; +/** + * + * @public + */ export interface KubernetesObjects { kubernetesObjects?: ObjectsByEntityResponse; loading: boolean; error?: string; } +/** + * + * @public + */ export const useKubernetesObjects = ( entity: Entity, intervalMs: number = 10000, diff --git a/plugins/kubernetes/src/hooks/useMatchingErrors.test.tsx b/plugins/kubernetes-react/src/hooks/useMatchingErrors.test.tsx similarity index 95% rename from plugins/kubernetes/src/hooks/useMatchingErrors.test.tsx rename to plugins/kubernetes-react/src/hooks/useMatchingErrors.test.tsx index 4ed4dbd73c..4d817e838d 100644 --- a/plugins/kubernetes/src/hooks/useMatchingErrors.test.tsx +++ b/plugins/kubernetes-react/src/hooks/useMatchingErrors.test.tsx @@ -16,8 +16,10 @@ import React from 'react'; import { renderHook } from '@testing-library/react-hooks'; import { DetectedErrorsContext, useMatchingErrors } from './useMatchingErrors'; -import { DetectedError } from '../error-detection'; -import { ResourceRef } from '../error-detection/types'; +import { + DetectedError, + ResourceRef, +} from '@backstage/plugin-kubernetes-common'; const genericErrorWithRef = (resourceRef: ResourceRef): DetectedError => { return { diff --git a/plugins/kubernetes/src/hooks/useMatchingErrors.ts b/plugins/kubernetes-react/src/hooks/useMatchingErrors.ts similarity index 95% rename from plugins/kubernetes/src/hooks/useMatchingErrors.ts rename to plugins/kubernetes-react/src/hooks/useMatchingErrors.ts index aa90d52cbb..1975065b7b 100644 --- a/plugins/kubernetes/src/hooks/useMatchingErrors.ts +++ b/plugins/kubernetes-react/src/hooks/useMatchingErrors.ts @@ -14,7 +14,10 @@ * limitations under the License. */ import React, { useContext } from 'react'; -import { DetectedError, ResourceRef } from '../error-detection/types'; +import { + DetectedError, + ResourceRef, +} from '@backstage/plugin-kubernetes-common'; import { TypeMeta } from '@kubernetes-models/base'; import { IIoK8sApimachineryPkgApisMetaV1ObjectMeta as V1ObjectMeta } from '@kubernetes-models/apimachinery/apis/meta/v1/ObjectMeta'; diff --git a/plugins/kubernetes/src/hooks/usePodMetrics.test.tsx b/plugins/kubernetes-react/src/hooks/usePodMetrics.test.tsx similarity index 100% rename from plugins/kubernetes/src/hooks/usePodMetrics.test.tsx rename to plugins/kubernetes-react/src/hooks/usePodMetrics.test.tsx diff --git a/plugins/kubernetes/src/hooks/usePodMetrics.ts b/plugins/kubernetes-react/src/hooks/usePodMetrics.ts similarity index 99% rename from plugins/kubernetes/src/hooks/usePodMetrics.ts rename to plugins/kubernetes-react/src/hooks/usePodMetrics.ts index 4392487cac..6d3c52690f 100644 --- a/plugins/kubernetes/src/hooks/usePodMetrics.ts +++ b/plugins/kubernetes-react/src/hooks/usePodMetrics.ts @@ -26,8 +26,8 @@ export const PodMetricsContext = React.createContext< Map >(new Map()); -/* - * @alpha +/** + * @public */ export type PodMetricsMatcher = { metadata?: IObjectMeta; diff --git a/plugins/kubernetes-react/src/index.ts b/plugins/kubernetes-react/src/index.ts new file mode 100644 index 0000000000..e5c84eab79 --- /dev/null +++ b/plugins/kubernetes-react/src/index.ts @@ -0,0 +1,29 @@ +/* + * 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. + */ + +/** + * Web library for the kubernetes-react plugin. + * + * @packageDocumentation + */ + +// In this package you might for example export components or hooks +// that are useful to other plugins or modules. + +export * from './hooks'; +export * from './api'; +export * from './kubernetes-auth-provider'; +export * from './components'; diff --git a/plugins/kubernetes/src/kubernetes-auth-provider/AksKubernetesAuthProvider.ts b/plugins/kubernetes-react/src/kubernetes-auth-provider/AksKubernetesAuthProvider.ts similarity index 98% rename from plugins/kubernetes/src/kubernetes-auth-provider/AksKubernetesAuthProvider.ts rename to plugins/kubernetes-react/src/kubernetes-auth-provider/AksKubernetesAuthProvider.ts index 401fc1e127..34a83dfed3 100644 --- a/plugins/kubernetes/src/kubernetes-auth-provider/AksKubernetesAuthProvider.ts +++ b/plugins/kubernetes-react/src/kubernetes-auth-provider/AksKubernetesAuthProvider.ts @@ -17,6 +17,7 @@ import { OAuthApi } from '@backstage/core-plugin-api'; import { KubernetesRequestBody } from '@backstage/plugin-kubernetes-common'; import { KubernetesAuthProvider } from './types'; +/** @public */ export class AksKubernetesAuthProvider implements KubernetesAuthProvider { constructor(private readonly microsoftAuthApi: OAuthApi) {} diff --git a/plugins/kubernetes/src/kubernetes-auth-provider/GoogleKubernetesAuthProvider.ts b/plugins/kubernetes-react/src/kubernetes-auth-provider/GoogleKubernetesAuthProvider.ts similarity index 99% rename from plugins/kubernetes/src/kubernetes-auth-provider/GoogleKubernetesAuthProvider.ts rename to plugins/kubernetes-react/src/kubernetes-auth-provider/GoogleKubernetesAuthProvider.ts index fbce644a89..9d7259b70e 100644 --- a/plugins/kubernetes/src/kubernetes-auth-provider/GoogleKubernetesAuthProvider.ts +++ b/plugins/kubernetes-react/src/kubernetes-auth-provider/GoogleKubernetesAuthProvider.ts @@ -18,6 +18,7 @@ import { KubernetesAuthProvider } from './types'; import { KubernetesRequestBody } from '@backstage/plugin-kubernetes-common'; import { OAuthApi } from '@backstage/core-plugin-api'; +/** @public */ export class GoogleKubernetesAuthProvider implements KubernetesAuthProvider { authProvider: OAuthApi; diff --git a/plugins/kubernetes/src/kubernetes-auth-provider/KubernetesAuthProviders.test.ts b/plugins/kubernetes-react/src/kubernetes-auth-provider/KubernetesAuthProviders.test.ts similarity index 100% rename from plugins/kubernetes/src/kubernetes-auth-provider/KubernetesAuthProviders.test.ts rename to plugins/kubernetes-react/src/kubernetes-auth-provider/KubernetesAuthProviders.test.ts diff --git a/plugins/kubernetes/src/kubernetes-auth-provider/KubernetesAuthProviders.ts b/plugins/kubernetes-react/src/kubernetes-auth-provider/KubernetesAuthProviders.ts similarity index 99% rename from plugins/kubernetes/src/kubernetes-auth-provider/KubernetesAuthProviders.ts rename to plugins/kubernetes-react/src/kubernetes-auth-provider/KubernetesAuthProviders.ts index 84154d5e96..77a7b156d7 100644 --- a/plugins/kubernetes/src/kubernetes-auth-provider/KubernetesAuthProviders.ts +++ b/plugins/kubernetes-react/src/kubernetes-auth-provider/KubernetesAuthProviders.ts @@ -22,6 +22,7 @@ import { OAuthApi, OpenIdConnectApi } from '@backstage/core-plugin-api'; import { OidcKubernetesAuthProvider } from './OidcKubernetesAuthProvider'; import { AksKubernetesAuthProvider } from './AksKubernetesAuthProvider'; +/** @public */ export class KubernetesAuthProviders implements KubernetesAuthProvidersApi { private readonly kubernetesAuthProviderMap: Map< string, diff --git a/plugins/kubernetes/src/kubernetes-auth-provider/OidcKubernetesAuthProvider.ts b/plugins/kubernetes-react/src/kubernetes-auth-provider/OidcKubernetesAuthProvider.ts similarity index 99% rename from plugins/kubernetes/src/kubernetes-auth-provider/OidcKubernetesAuthProvider.ts rename to plugins/kubernetes-react/src/kubernetes-auth-provider/OidcKubernetesAuthProvider.ts index b2e6c5cbc2..c117200f56 100644 --- a/plugins/kubernetes/src/kubernetes-auth-provider/OidcKubernetesAuthProvider.ts +++ b/plugins/kubernetes-react/src/kubernetes-auth-provider/OidcKubernetesAuthProvider.ts @@ -19,6 +19,7 @@ import { KubernetesRequestBody } from '@backstage/plugin-kubernetes-common'; import { OpenIdConnectApi } from '@backstage/core-plugin-api'; import { KubernetesAuthProvider } from './types'; +/** @public */ export class OidcKubernetesAuthProvider implements KubernetesAuthProvider { providerName: string; authProvider: OpenIdConnectApi; diff --git a/plugins/kubernetes/src/kubernetes-auth-provider/ServerSideAuthProvider.ts b/plugins/kubernetes-react/src/kubernetes-auth-provider/ServerSideAuthProvider.ts similarity index 100% rename from plugins/kubernetes/src/kubernetes-auth-provider/ServerSideAuthProvider.ts rename to plugins/kubernetes-react/src/kubernetes-auth-provider/ServerSideAuthProvider.ts diff --git a/plugins/kubernetes/src/error-detection/index.ts b/plugins/kubernetes-react/src/kubernetes-auth-provider/index.ts similarity index 70% rename from plugins/kubernetes/src/error-detection/index.ts rename to plugins/kubernetes-react/src/kubernetes-auth-provider/index.ts index 3a8789d79d..5ab8b0be43 100644 --- a/plugins/kubernetes/src/error-detection/index.ts +++ b/plugins/kubernetes-react/src/kubernetes-auth-provider/index.ts @@ -14,10 +14,9 @@ * limitations under the License. */ -export type { - DetectedError, - DetectedErrorsByCluster, - ErrorSeverity, - ResourceRef, -} from './types'; -export { detectErrors } from './error-detection'; +export * from './types'; +export * from './KubernetesAuthProviders'; +export * from './GoogleKubernetesAuthProvider'; +export * from './ServerSideAuthProvider'; +export * from './OidcKubernetesAuthProvider'; +export * from './AksKubernetesAuthProvider'; diff --git a/plugins/kubernetes/src/kubernetes-auth-provider/types.ts b/plugins/kubernetes-react/src/kubernetes-auth-provider/types.ts similarity index 96% rename from plugins/kubernetes/src/kubernetes-auth-provider/types.ts rename to plugins/kubernetes-react/src/kubernetes-auth-provider/types.ts index 418758dd31..adf323d1d8 100644 --- a/plugins/kubernetes/src/kubernetes-auth-provider/types.ts +++ b/plugins/kubernetes-react/src/kubernetes-auth-provider/types.ts @@ -17,6 +17,7 @@ import { KubernetesRequestBody } from '@backstage/plugin-kubernetes-common'; import { createApiRef } from '@backstage/core-plugin-api'; +/** @public */ export interface KubernetesAuthProvider { decorateRequestBodyForAuth( requestBody: KubernetesRequestBody, @@ -24,11 +25,13 @@ export interface KubernetesAuthProvider { getCredentials(): Promise<{ token?: string }>; } +/** @public */ export const kubernetesAuthProvidersApiRef = createApiRef({ id: 'plugin.kubernetes-auth-providers.service', }); +/** @public */ export interface KubernetesAuthProvidersApi { decorateRequestBodyForAuth( authProvider: string, diff --git a/plugins/kubernetes-react/src/setupTests.ts b/plugins/kubernetes-react/src/setupTests.ts new file mode 100644 index 0000000000..865308e634 --- /dev/null +++ b/plugins/kubernetes-react/src/setupTests.ts @@ -0,0 +1,16 @@ +/* + * 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 '@testing-library/jest-dom'; diff --git a/plugins/kubernetes/src/types/index.ts b/plugins/kubernetes-react/src/types/index.ts similarity index 100% rename from plugins/kubernetes/src/types/index.ts rename to plugins/kubernetes-react/src/types/index.ts diff --git a/plugins/kubernetes-react/src/types/types.ts b/plugins/kubernetes-react/src/types/types.ts new file mode 100644 index 0000000000..7efd1ef3ff --- /dev/null +++ b/plugins/kubernetes-react/src/types/types.ts @@ -0,0 +1,28 @@ +/* + * Copyright 2020 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 type { JsonObject } from '@backstage/types'; + +export interface ClusterLinksFormatterOptions { + dashboardUrl?: URL; + dashboardParameters?: JsonObject; + object: any; + kind: string; +} + +export type ClusterLinksFormatter = ( + options: ClusterLinksFormatterOptions, +) => URL; diff --git a/plugins/kubernetes/src/utils/clusterLinks/formatClusterLink.test.ts b/plugins/kubernetes-react/src/utils/clusterLinks/formatClusterLink.test.ts similarity index 100% rename from plugins/kubernetes/src/utils/clusterLinks/formatClusterLink.test.ts rename to plugins/kubernetes-react/src/utils/clusterLinks/formatClusterLink.test.ts diff --git a/plugins/kubernetes/src/utils/clusterLinks/formatClusterLink.ts b/plugins/kubernetes-react/src/utils/clusterLinks/formatClusterLink.ts similarity index 90% rename from plugins/kubernetes/src/utils/clusterLinks/formatClusterLink.ts rename to plugins/kubernetes-react/src/utils/clusterLinks/formatClusterLink.ts index 6a998bbce2..ae3bdb950f 100644 --- a/plugins/kubernetes/src/utils/clusterLinks/formatClusterLink.ts +++ b/plugins/kubernetes-react/src/utils/clusterLinks/formatClusterLink.ts @@ -17,6 +17,7 @@ import type { JsonObject } from '@backstage/types'; import { defaultFormatterName, clusterLinksFormatters } from './formatters'; +// @Deprecated use import { FormatClusterLinkOptions } from '@backstage/kubernetes-react' export type FormatClusterLinkOptions = { dashboardUrl?: string; dashboardApp?: string; @@ -25,6 +26,7 @@ export type FormatClusterLinkOptions = { kind: string; }; +// @Deprecated use import { formatClusterLink } from '@backstage/kubernetes-react' export function formatClusterLink(options: FormatClusterLinkOptions) { if (!options.dashboardUrl && !options.dashboardParameters) { return undefined; diff --git a/plugins/kubernetes/src/utils/clusterLinks/formatters/aks.test.ts b/plugins/kubernetes-react/src/utils/clusterLinks/formatters/aks.test.ts similarity index 100% rename from plugins/kubernetes/src/utils/clusterLinks/formatters/aks.test.ts rename to plugins/kubernetes-react/src/utils/clusterLinks/formatters/aks.test.ts diff --git a/plugins/kubernetes/src/utils/clusterLinks/formatters/aks.ts b/plugins/kubernetes-react/src/utils/clusterLinks/formatters/aks.ts similarity index 100% rename from plugins/kubernetes/src/utils/clusterLinks/formatters/aks.ts rename to plugins/kubernetes-react/src/utils/clusterLinks/formatters/aks.ts diff --git a/plugins/kubernetes/src/utils/clusterLinks/formatters/eks.test.ts b/plugins/kubernetes-react/src/utils/clusterLinks/formatters/eks.test.ts similarity index 100% rename from plugins/kubernetes/src/utils/clusterLinks/formatters/eks.test.ts rename to plugins/kubernetes-react/src/utils/clusterLinks/formatters/eks.test.ts diff --git a/plugins/kubernetes/src/utils/clusterLinks/formatters/eks.ts b/plugins/kubernetes-react/src/utils/clusterLinks/formatters/eks.ts similarity index 100% rename from plugins/kubernetes/src/utils/clusterLinks/formatters/eks.ts rename to plugins/kubernetes-react/src/utils/clusterLinks/formatters/eks.ts diff --git a/plugins/kubernetes/src/utils/clusterLinks/formatters/gke.test.ts b/plugins/kubernetes-react/src/utils/clusterLinks/formatters/gke.test.ts similarity index 100% rename from plugins/kubernetes/src/utils/clusterLinks/formatters/gke.test.ts rename to plugins/kubernetes-react/src/utils/clusterLinks/formatters/gke.test.ts diff --git a/plugins/kubernetes/src/utils/clusterLinks/formatters/gke.ts b/plugins/kubernetes-react/src/utils/clusterLinks/formatters/gke.ts similarity index 100% rename from plugins/kubernetes/src/utils/clusterLinks/formatters/gke.ts rename to plugins/kubernetes-react/src/utils/clusterLinks/formatters/gke.ts diff --git a/plugins/kubernetes/src/utils/clusterLinks/formatters/index.ts b/plugins/kubernetes-react/src/utils/clusterLinks/formatters/index.ts similarity index 100% rename from plugins/kubernetes/src/utils/clusterLinks/formatters/index.ts rename to plugins/kubernetes-react/src/utils/clusterLinks/formatters/index.ts diff --git a/plugins/kubernetes/src/utils/clusterLinks/formatters/openshift.test.ts b/plugins/kubernetes-react/src/utils/clusterLinks/formatters/openshift.test.ts similarity index 100% rename from plugins/kubernetes/src/utils/clusterLinks/formatters/openshift.test.ts rename to plugins/kubernetes-react/src/utils/clusterLinks/formatters/openshift.test.ts diff --git a/plugins/kubernetes/src/utils/clusterLinks/formatters/openshift.ts b/plugins/kubernetes-react/src/utils/clusterLinks/formatters/openshift.ts similarity index 100% rename from plugins/kubernetes/src/utils/clusterLinks/formatters/openshift.ts rename to plugins/kubernetes-react/src/utils/clusterLinks/formatters/openshift.ts diff --git a/plugins/kubernetes/src/utils/clusterLinks/formatters/rancher.test.ts b/plugins/kubernetes-react/src/utils/clusterLinks/formatters/rancher.test.ts similarity index 100% rename from plugins/kubernetes/src/utils/clusterLinks/formatters/rancher.test.ts rename to plugins/kubernetes-react/src/utils/clusterLinks/formatters/rancher.test.ts diff --git a/plugins/kubernetes/src/utils/clusterLinks/formatters/rancher.ts b/plugins/kubernetes-react/src/utils/clusterLinks/formatters/rancher.ts similarity index 100% rename from plugins/kubernetes/src/utils/clusterLinks/formatters/rancher.ts rename to plugins/kubernetes-react/src/utils/clusterLinks/formatters/rancher.ts diff --git a/plugins/kubernetes/src/utils/clusterLinks/formatters/standard.test.ts b/plugins/kubernetes-react/src/utils/clusterLinks/formatters/standard.test.ts similarity index 100% rename from plugins/kubernetes/src/utils/clusterLinks/formatters/standard.test.ts rename to plugins/kubernetes-react/src/utils/clusterLinks/formatters/standard.test.ts diff --git a/plugins/kubernetes/src/utils/clusterLinks/formatters/standard.ts b/plugins/kubernetes-react/src/utils/clusterLinks/formatters/standard.ts similarity index 100% rename from plugins/kubernetes/src/utils/clusterLinks/formatters/standard.ts rename to plugins/kubernetes-react/src/utils/clusterLinks/formatters/standard.ts diff --git a/plugins/kubernetes/src/utils/clusterLinks/index.ts b/plugins/kubernetes-react/src/utils/clusterLinks/index.ts similarity index 100% rename from plugins/kubernetes/src/utils/clusterLinks/index.ts rename to plugins/kubernetes-react/src/utils/clusterLinks/index.ts diff --git a/plugins/kubernetes/src/utils/crons.test.ts b/plugins/kubernetes-react/src/utils/crons.test.ts similarity index 100% rename from plugins/kubernetes/src/utils/crons.test.ts rename to plugins/kubernetes-react/src/utils/crons.test.ts diff --git a/plugins/kubernetes/src/utils/crons.ts b/plugins/kubernetes-react/src/utils/crons.ts similarity index 100% rename from plugins/kubernetes/src/utils/crons.ts rename to plugins/kubernetes-react/src/utils/crons.ts diff --git a/plugins/kubernetes/src/utils/index.ts b/plugins/kubernetes-react/src/utils/index.ts similarity index 100% rename from plugins/kubernetes/src/utils/index.ts rename to plugins/kubernetes-react/src/utils/index.ts diff --git a/plugins/kubernetes/src/utils/owner.test.ts b/plugins/kubernetes-react/src/utils/owner.test.ts similarity index 100% rename from plugins/kubernetes/src/utils/owner.test.ts rename to plugins/kubernetes-react/src/utils/owner.test.ts diff --git a/plugins/kubernetes/src/utils/owner.ts b/plugins/kubernetes-react/src/utils/owner.ts similarity index 100% rename from plugins/kubernetes/src/utils/owner.ts rename to plugins/kubernetes-react/src/utils/owner.ts diff --git a/plugins/kubernetes/src/utils/pod.test.tsx b/plugins/kubernetes-react/src/utils/pod.test.tsx similarity index 100% rename from plugins/kubernetes/src/utils/pod.test.tsx rename to plugins/kubernetes-react/src/utils/pod.test.tsx diff --git a/plugins/kubernetes/src/utils/pod.tsx b/plugins/kubernetes-react/src/utils/pod.tsx similarity index 100% rename from plugins/kubernetes/src/utils/pod.tsx rename to plugins/kubernetes-react/src/utils/pod.tsx diff --git a/plugins/kubernetes/src/utils/resources.ts b/plugins/kubernetes-react/src/utils/resources.ts similarity index 100% rename from plugins/kubernetes/src/utils/resources.ts rename to plugins/kubernetes-react/src/utils/resources.ts diff --git a/plugins/kubernetes/api-report.md b/plugins/kubernetes/api-report.md index d1c1748758..64b56cf786 100644 --- a/plugins/kubernetes/api-report.md +++ b/plugins/kubernetes/api-report.md @@ -5,162 +5,10 @@ ```ts /// -import { ApiRef } from '@backstage/core-plugin-api'; -import { AsyncState } from 'react-use/lib/useAsyncFn'; import { BackstagePlugin } from '@backstage/core-plugin-api'; -import { ClientContainerStatus } from '@backstage/plugin-kubernetes-common'; -import { ClientPodStatus } from '@backstage/plugin-kubernetes-common'; -import { ClusterAttributes } from '@backstage/plugin-kubernetes-common'; -import { ClusterObjects } from '@backstage/plugin-kubernetes-common'; -import { CustomObjectsByEntityRequest } from '@backstage/plugin-kubernetes-common'; -import { CustomResourceMatcher } from '@backstage/plugin-kubernetes-common'; -import { DiscoveryApi } from '@backstage/core-plugin-api'; import { Entity } from '@backstage/catalog-model'; -import { Event as Event_2 } from 'kubernetes-models/v1'; -import { IContainer } from 'kubernetes-models/v1'; -import { IContainerStatus } from 'kubernetes-models/v1'; -import { IdentityApi } from '@backstage/core-plugin-api'; -import { IIoK8sApimachineryPkgApisMetaV1ObjectMeta } from '@kubernetes-models/apimachinery/apis/meta/v1/ObjectMeta'; -import { IObjectMeta } from '@kubernetes-models/apimachinery/apis/meta/v1/ObjectMeta'; -import type { JsonObject } from '@backstage/types'; -import { KubernetesRequestBody } from '@backstage/plugin-kubernetes-common'; -import { OAuthApi } from '@backstage/core-plugin-api'; -import { ObjectsByEntityResponse } from '@backstage/plugin-kubernetes-common'; -import { OpenIdConnectApi } from '@backstage/core-plugin-api'; -import { Pod } from 'kubernetes-models/v1/Pod'; -import { Pod as Pod_2 } from 'kubernetes-models/v1'; import { default as React_2 } from 'react'; -import * as React_3 from 'react'; import { RouteRef } from '@backstage/core-plugin-api'; -import { TypeMeta } from '@kubernetes-models/base'; -import { V1ConfigMap } from '@kubernetes/client-node'; -import { V1CronJob } from '@kubernetes/client-node'; -import { V1Deployment } from '@kubernetes/client-node'; -import { V1HorizontalPodAutoscaler } from '@kubernetes/client-node'; -import { V1Ingress } from '@kubernetes/client-node'; -import { V1Job } from '@kubernetes/client-node'; -import { V1ObjectMeta } from '@kubernetes/client-node'; -import { V1Pod } from '@kubernetes/client-node'; -import { V1ReplicaSet } from '@kubernetes/client-node'; -import { V1Service } from '@kubernetes/client-node'; -import { V1StatefulSet } from '@kubernetes/client-node'; -import { WorkloadsByEntityRequest } from '@backstage/plugin-kubernetes-common'; - -// Warning: (ae-forgotten-export) The symbol "ClusterProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "Cluster" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const Cluster: ({ - clusterObjects, - podsWithErrors, -}: ClusterProps) => React_2.JSX.Element; - -// Warning: (ae-missing-release-tag) "ClusterContext" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const ClusterContext: React_2.Context; - -// Warning: (ae-missing-release-tag) "ClusterLinksFormatter" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export type ClusterLinksFormatter = ( - options: ClusterLinksFormatterOptions, -) => URL; - -// Warning: (ae-missing-release-tag) "ClusterLinksFormatterOptions" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export interface ClusterLinksFormatterOptions { - // (undocumented) - dashboardParameters?: JsonObject; - // (undocumented) - dashboardUrl?: URL; - // (undocumented) - kind: string; - // (undocumented) - object: any; -} - -// Warning: (ae-missing-release-tag) "clusterLinksFormatters" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const clusterLinksFormatters: Record; - -// @public -export const ContainerCard: React_2.FC; - -// @public -export interface ContainerCardProps { - // (undocumented) - containerMetrics?: ClientContainerStatus; - // (undocumented) - containerSpec?: IContainer; - // (undocumented) - containerStatus: IContainerStatus; - // (undocumented) - podScope: PodScope; -} - -// @public -export interface ContainerScope extends PodScope { - // (undocumented) - containerName: string; -} - -// Warning: (ae-forgotten-export) The symbol "CronJobsAccordionsProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "CronJobsAccordions" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const CronJobsAccordions: ({}: CronJobsAccordionsProps) => React_2.JSX.Element; - -// Warning: (ae-forgotten-export) The symbol "CustomResourcesProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "CustomResources" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const CustomResources: ({}: CustomResourcesProps) => React_2.JSX.Element; - -// Warning: (ae-missing-release-tag) "DeploymentResources" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export interface DeploymentResources { - // (undocumented) - deployments: V1Deployment[]; - // (undocumented) - horizontalPodAutoscalers: V1HorizontalPodAutoscaler[]; - // (undocumented) - pods: V1Pod[]; - // (undocumented) - replicaSets: V1ReplicaSet[]; -} - -// @public -export interface DetectedError { - // (undocumented) - message: string; - // (undocumented) - occurrenceCount: number; - // Warning: (ae-forgotten-export) The symbol "ProposedFix" needs to be exported by the entry point index.d.ts - // - // (undocumented) - proposedFix?: ProposedFix; - // (undocumented) - severity: ErrorSeverity; - // (undocumented) - sourceRef: ResourceRef; - // (undocumented) - type: string; -} - -// @public -export type DetectedErrorsByCluster = Map; - -// @public -export const DetectedErrorsContext: React_2.Context; - -// @public -export const detectErrors: ( - objects: ObjectsByEntityResponse, -) => DetectedErrorsByCluster; // Warning: (ae-missing-release-tag) "EntityKubernetesContent" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -174,338 +22,11 @@ export type EntityKubernetesContentProps = { refreshIntervalMs?: number; }; -// @public -export const ErrorList: ({ - podAndErrors, -}: ErrorListProps) => React_2.JSX.Element; - -// @public -export interface ErrorListProps { - // (undocumented) - podAndErrors: PodAndErrors[]; -} - -// @public (undocumented) -export type ErrorMatcher = { - metadata?: IIoK8sApimachineryPkgApisMetaV1ObjectMeta; -} & TypeMeta; - -// Warning: (ae-forgotten-export) The symbol "ErrorPanelProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "ErrorPanel" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const ErrorPanel: ({ - entityName, - errorMessage, - clustersWithErrors, -}: ErrorPanelProps) => React_2.JSX.Element; - -// Warning: (ae-forgotten-export) The symbol "ErrorReportingProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "ErrorReporting" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const ErrorReporting: ({ - detectedErrors, -}: ErrorReportingProps) => React_3.JSX.Element; - -// @public -export type ErrorSeverity = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10; - -// @public -export const Events: ({ - involvedObjectName, - namespace, - clusterName, - warningEventsOnly, -}: EventsProps) => React_2.JSX.Element; - -// @public -export const EventsContent: ({ - events, - warningEventsOnly, -}: EventsContentProps) => React_2.JSX.Element; - -// @public -export interface EventsContentProps { - // (undocumented) - events: Event_2[]; - // (undocumented) - warningEventsOnly?: boolean; -} - -// @public -export interface EventsOptions { - // (undocumented) - clusterName: string; - // (undocumented) - involvedObjectName: string; - // (undocumented) - namespace: string; -} - -// @public -export interface EventsProps { - // (undocumented) - clusterName: string; - // (undocumented) - involvedObjectName: string; - // (undocumented) - namespace: string; - // (undocumented) - warningEventsOnly?: boolean; -} - -// @public -export const FixDialog: React_2.FC; - -// @public -export interface FixDialogProps { - // (undocumented) - clusterName: string; - // (undocumented) - error: DetectedError; - // (undocumented) - open?: boolean; - // (undocumented) - pod: Pod; -} - -// Warning: (ae-forgotten-export) The symbol "FormatClusterLinkOptions" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "formatClusterLink" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export function formatClusterLink( - options: FormatClusterLinkOptions, -): string | undefined; - -// Warning: (ae-forgotten-export) The symbol "KubernetesAuthProvider" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "GoogleKubernetesAuthProvider" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export class GoogleKubernetesAuthProvider implements KubernetesAuthProvider { - constructor(authProvider: OAuthApi); - // (undocumented) - authProvider: OAuthApi; - // (undocumented) - decorateRequestBodyForAuth( - requestBody: KubernetesRequestBody, - ): Promise; - // (undocumented) - getCredentials(): Promise<{ - token: string; - }>; -} - -// Warning: (ae-missing-release-tag) "GroupedResponses" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export interface GroupedResponses extends DeploymentResources { - // (undocumented) - configMaps: V1ConfigMap[]; - // (undocumented) - cronJobs: V1CronJob[]; - // (undocumented) - customResources: any[]; - // (undocumented) - ingresses: V1Ingress[]; - // (undocumented) - jobs: V1Job[]; - // (undocumented) - services: V1Service[]; - // (undocumented) - statefulsets: V1StatefulSet[]; -} - -// Warning: (ae-missing-release-tag) "GroupedResponsesContext" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const GroupedResponsesContext: React_2.Context; - -// @public (undocumented) -export const HorizontalPodAutoscalerDrawer: (props: { - hpa: V1HorizontalPodAutoscaler; - expanded?: boolean; - children?: React_2.ReactNode; -}) => React_2.JSX.Element; - -// Warning: (ae-forgotten-export) The symbol "IngressesAccordionsProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "IngressesAccordions" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const IngressesAccordions: ({}: IngressesAccordionsProps) => React_2.JSX.Element; - // Warning: (ae-missing-release-tag) "isKubernetesAvailable" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const isKubernetesAvailable: (entity: Entity) => boolean; -// Warning: (ae-forgotten-export) The symbol "JobsAccordionsProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "JobsAccordions" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const JobsAccordions: ({ - jobs, -}: JobsAccordionsProps) => React_2.JSX.Element; - -// Warning: (ae-missing-release-tag) "KubernetesApi" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export interface KubernetesApi { - // (undocumented) - getClusters(): Promise< - { - name: string; - authProvider: string; - oidcTokenProvider?: string | undefined; - }[] - >; - // (undocumented) - getCustomObjectsByEntity( - request: CustomObjectsByEntityRequest, - ): Promise; - // (undocumented) - getObjectsByEntity( - requestBody: KubernetesRequestBody, - ): Promise; - // (undocumented) - getWorkloadsByEntity( - request: WorkloadsByEntityRequest, - ): Promise; - // (undocumented) - proxy(options: { - clusterName: string; - path: string; - init?: RequestInit; - }): Promise; -} - -// Warning: (ae-missing-release-tag) "kubernetesApiRef" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const kubernetesApiRef: ApiRef; - -// Warning: (ae-missing-release-tag) "KubernetesAuthProviders" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export class KubernetesAuthProviders implements KubernetesAuthProvidersApi { - constructor(options: { - microsoftAuthApi: OAuthApi; - googleAuthApi: OAuthApi; - oidcProviders?: { - [key: string]: OpenIdConnectApi; - }; - }); - // (undocumented) - decorateRequestBodyForAuth( - authProvider: string, - requestBody: KubernetesRequestBody, - ): Promise; - // (undocumented) - getCredentials(authProvider: string): Promise<{ - token?: string; - }>; -} - -// Warning: (ae-missing-release-tag) "KubernetesAuthProvidersApi" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export interface KubernetesAuthProvidersApi { - // (undocumented) - decorateRequestBodyForAuth( - authProvider: string, - requestBody: KubernetesRequestBody, - ): Promise; - // (undocumented) - getCredentials(authProvider: string): Promise<{ - token?: string; - }>; -} - -// Warning: (ae-missing-release-tag) "kubernetesAuthProvidersApiRef" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const kubernetesAuthProvidersApiRef: ApiRef; - -// Warning: (ae-missing-release-tag) "KubernetesBackendClient" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export class KubernetesBackendClient implements KubernetesApi { - constructor(options: { - discoveryApi: DiscoveryApi; - identityApi: IdentityApi; - kubernetesAuthProvidersApi: KubernetesAuthProvidersApi; - }); - // (undocumented) - getClusters(): Promise< - { - name: string; - authProvider: string; - }[] - >; - // (undocumented) - getCustomObjectsByEntity( - request: CustomObjectsByEntityRequest, - ): Promise; - // (undocumented) - getObjectsByEntity( - requestBody: KubernetesRequestBody, - ): Promise; - // (undocumented) - getWorkloadsByEntity( - request: WorkloadsByEntityRequest, - ): Promise; - // (undocumented) - proxy(options: { - clusterName: string; - path: string; - init?: RequestInit; - }): Promise; -} - -// Warning: (ae-forgotten-export) The symbol "KubernetesContentProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "KubernetesContent" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const KubernetesContent: ({ - entity, - refreshIntervalMs, -}: KubernetesContentProps) => React_2.JSX.Element; - -// Warning: (ae-forgotten-export) The symbol "KubernetesDrawerProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "KubernetesDrawer" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const KubernetesDrawer: ({ - open, - label, - drawerContentsHeader, - kubernetesObject, - children, -}: KubernetesDrawerProps) => React_2.JSX.Element; - -// Warning: (ae-forgotten-export) The symbol "KubernetesDrawerContentProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "KubernetesDrawerContent" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const KubernetesDrawerContent: ({ - children, - header, - kubernetesObject, - close, -}: KubernetesDrawerContentProps) => React_2.JSX.Element; - -// Warning: (ae-missing-release-tag) "KubernetesObjects" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export interface KubernetesObjects { - // (undocumented) - error?: string; - // (undocumented) - kubernetesObjects?: ObjectsByEntityResponse; - // (undocumented) - loading: boolean; -} - // Warning: (ae-missing-release-tag) "kubernetesPlugin" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -518,234 +39,6 @@ const kubernetesPlugin: BackstagePlugin< export { kubernetesPlugin }; export { kubernetesPlugin as plugin }; -// Warning: (ae-missing-release-tag) "KubernetesProxyApi" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export interface KubernetesProxyApi { - // (undocumented) - getEventsByInvolvedObjectName(request: { - clusterName: string; - involvedObjectName: string; - namespace: string; - }): Promise; - // (undocumented) - getPodLogs(request: { - podName: string; - namespace: string; - clusterName: string; - containerName: string; - previous?: boolean; - }): Promise<{ - text: string; - }>; -} - -// Warning: (ae-missing-release-tag) "kubernetesProxyApiRef" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const kubernetesProxyApiRef: ApiRef; - -// @public -export class KubernetesProxyClient { - constructor(options: { kubernetesApi: KubernetesApi }); - // (undocumented) - getEventsByInvolvedObjectName({ - clusterName, - involvedObjectName, - namespace, - }: { - clusterName: string; - involvedObjectName: string; - namespace: string; - }): Promise; - // (undocumented) - getPodLogs({ - podName, - namespace, - clusterName, - containerName, - previous, - }: { - podName: string; - namespace: string; - clusterName: string; - containerName: string; - previous?: boolean; - }): Promise<{ - text: string; - }>; -} - -// Warning: (ae-forgotten-export) The symbol "KubernetesDrawerable" needs to be exported by the entry point index.d.ts -// Warning: (ae-forgotten-export) The symbol "KubernetesStructuredMetadataTableDrawerProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "KubernetesStructuredMetadataTableDrawer" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const KubernetesStructuredMetadataTableDrawer: < - T extends KubernetesDrawerable, ->({ - object, - renderObject, - kind, - buttonVariant, - expanded, - children, -}: KubernetesStructuredMetadataTableDrawerProps) => React_2.JSX.Element; - -// Warning: (ae-forgotten-export) The symbol "ErrorPanelProps_2" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "LinkErrorPanel" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const LinkErrorPanel: ({ - cluster, - errorMessage, -}: ErrorPanelProps_2) => React_2.JSX.Element; - -// @public -export const PendingPodContent: ({ - pod, -}: PendingPodContentProps) => React_2.JSX.Element; - -// @public -export interface PendingPodContentProps { - // (undocumented) - pod: Pod_2; -} - -// @public -export interface PodAndErrors { - // (undocumented) - clusterName: string; - // (undocumented) - errors: DetectedError[]; - // (undocumented) - pod: Pod_2; -} - -// Warning: (ae-forgotten-export) The symbol "PodDrawerProps" needs to be exported by the entry point index.d.ts -// -// @public -export const PodDrawer: ({ - podAndErrors, - open, -}: PodDrawerProps) => React_2.JSX.Element; - -// @public -export const PodExecTerminal: ( - props: PodExecTerminalProps, -) => React_2.JSX.Element; - -// @public -export const PodExecTerminalDialog: ( - props: PodExecTerminalProps, -) => React_2.JSX.Element; - -// @public -export interface PodExecTerminalProps { - // (undocumented) - clusterName: string; - // (undocumented) - containerName: string; - // (undocumented) - podName: string; - // (undocumented) - podNamespace: string; -} - -// @public -export const PodLogs: React_2.FC; - -// @public -export const PodLogsDialog: ({ - containerScope, -}: PodLogsDialogProps) => React_2.JSX.Element; - -// @public -export interface PodLogsDialogProps { - // (undocumented) - containerScope: ContainerScope; -} - -// @public -export interface PodLogsOptions { - // (undocumented) - containerScope: ContainerScope; - // (undocumented) - previous?: boolean; -} - -// @public -export interface PodLogsProps { - // (undocumented) - containerScope: ContainerScope; - // (undocumented) - previous?: boolean; -} - -// @public -export const PodMetricsContext: React_2.Context>; - -// Warning: (ae-missing-release-tag) "PodMetricsMatcher" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export type PodMetricsMatcher = { - metadata?: IObjectMeta; -}; - -// Warning: (ae-missing-release-tag) "PodNamesWithErrorsContext" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const PodNamesWithErrorsContext: React_2.Context>; - -// Warning: (ae-missing-release-tag) "PodNamesWithMetricsContext" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const PodNamesWithMetricsContext: React_2.Context< - Map ->; - -// @public -export interface PodScope { - // (undocumented) - clusterName: string; - // (undocumented) - podName: string; - // (undocumented) - podNamespace: string; -} - -// Warning: (ae-forgotten-export) The symbol "PodsTablesProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "PodsTable" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const PodsTable: ({ - pods, - extraColumns, -}: PodsTablesProps) => React_2.JSX.Element; - -// @public -export interface ResourceRef { - // (undocumented) - apiGroup: string; - // (undocumented) - kind: string; - // (undocumented) - name: string; - // (undocumented) - namespace: string; -} - -// Warning: (ae-forgotten-export) The symbol "ResourceUtilizationProps" needs to be exported by the entry point index.d.ts -// -// @public -export const ResourceUtilization: ({ - compressed, - title, - usage, - total, - totalFormatted, -}: ResourceUtilizationProps) => React_2.JSX.Element; - // Warning: (ae-missing-release-tag) "Router" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -753,60 +46,5 @@ export const Router: (props: { refreshIntervalMs?: number; }) => React_2.JSX.Element; -// @public -export class ServerSideKubernetesAuthProvider - implements KubernetesAuthProvider -{ - // (undocumented) - decorateRequestBodyForAuth( - requestBody: KubernetesRequestBody, - ): Promise; - // (undocumented) - getCredentials(): Promise<{}>; -} - -// Warning: (ae-forgotten-export) The symbol "ServicesAccordionsProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "ServicesAccordions" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const ServicesAccordions: ({}: ServicesAccordionsProps) => React_2.JSX.Element; - -// @public -export const useCustomResources: ( - entity: Entity, - customResourceMatchers: CustomResourceMatcher[], - intervalMs?: number, -) => KubernetesObjects; - -// @public -export const useEvents: ({ - involvedObjectName, - namespace, - clusterName, -}: EventsOptions) => AsyncState; - -// Warning: (ae-missing-release-tag) "useKubernetesObjects" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const useKubernetesObjects: ( - entity: Entity, - intervalMs?: number, -) => KubernetesObjects; - -// @public -export const useMatchingErrors: (matcher: ErrorMatcher) => DetectedError[]; - -// @public -export const usePodLogs: ({ - containerScope, - previous, -}: PodLogsOptions) => AsyncState<{ - text: string; -}>; - -// @public -export const usePodMetrics: ( - clusterName: string, - matcher: PodMetricsMatcher, -) => ClientPodStatus | undefined; +export * from '@backstage/plugin-kubernetes-react'; ``` diff --git a/plugins/kubernetes/package.json b/plugins/kubernetes/package.json index 7f66af1296..fdc792fc52 100644 --- a/plugins/kubernetes/package.json +++ b/plugins/kubernetes/package.json @@ -41,6 +41,7 @@ "@backstage/errors": "workspace:^", "@backstage/plugin-catalog-react": "workspace:^", "@backstage/plugin-kubernetes-common": "workspace:^", + "@backstage/plugin-kubernetes-react": "workspace:^", "@backstage/theme": "workspace:^", "@backstage/types": "workspace:^", "@kubernetes-models/apimachinery": "^1.1.0", diff --git a/plugins/kubernetes/src/components/KubernetesContent.test.tsx b/plugins/kubernetes/src/KubernetesContent.test.tsx similarity index 91% rename from plugins/kubernetes/src/components/KubernetesContent.test.tsx rename to plugins/kubernetes/src/KubernetesContent.test.tsx index 4c85298dba..7c21c6f5a7 100644 --- a/plugins/kubernetes/src/components/KubernetesContent.test.tsx +++ b/plugins/kubernetes/src/KubernetesContent.test.tsx @@ -18,13 +18,19 @@ import React from 'react'; import { screen } from '@testing-library/react'; import { renderInTestApp } from '@backstage/test-utils'; import { KubernetesContent } from './KubernetesContent'; -import { useKubernetesObjects } from '../hooks'; +import { useKubernetesObjects } from '@backstage/plugin-kubernetes-react'; +import * as oneDeployment from './__fixtures__/1-deployments.json'; +import * as twoDeployments from './__fixtures__/2-deployments.json'; -jest.mock('../hooks'); -import * as oneDeployment from '../__fixtures__/1-deployments.json'; -import * as twoDeployments from '../__fixtures__/2-deployments.json'; +jest.mock('@backstage/plugin-kubernetes-react', () => ({ + ...jest.requireActual('@backstage/plugin-kubernetes-react'), + useKubernetesObjects: jest.fn(), +})); describe('KubernetesContent', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); it('render empty response', async () => { (useKubernetesObjects as any).mockReturnValue({ kubernetesObjects: { diff --git a/plugins/kubernetes/src/components/KubernetesContent.tsx b/plugins/kubernetes/src/KubernetesContent.tsx similarity index 81% rename from plugins/kubernetes/src/components/KubernetesContent.tsx rename to plugins/kubernetes/src/KubernetesContent.tsx index a465422095..9c266b1854 100644 --- a/plugins/kubernetes/src/components/KubernetesContent.tsx +++ b/plugins/kubernetes/src/KubernetesContent.tsx @@ -17,14 +17,23 @@ import React from 'react'; import { Grid, Typography } from '@material-ui/core'; import { Entity } from '@backstage/catalog-model'; -import { ErrorPanel } from './ErrorPanel'; -import { ErrorReporting } from './ErrorReporting'; -import { DetectedError, detectErrors } from '../error-detection'; -import { Cluster } from './Cluster'; -import EmptyStateImage from '../assets/emptystate.svg'; -import { useKubernetesObjects } from '../hooks'; -import { Content, Page, Progress } from '@backstage/core-components'; -import { DetectedErrorsContext } from '../hooks/useMatchingErrors'; +import { + ErrorPanel, + ErrorReporting, + Cluster, + useKubernetesObjects, + DetectedErrorsContext, +} from '@backstage/plugin-kubernetes-react'; +import { + DetectedError, + detectErrors, +} from '@backstage/plugin-kubernetes-common'; +import { + Content, + EmptyState, + Page, + Progress, +} from '@backstage/core-components'; type KubernetesContentProps = { entity: Entity; @@ -98,17 +107,11 @@ export const KubernetesContent = ({ alignItems="center" spacing={2} > - - - No resources on any known clusters for{' '} - {entity.metadata.name} - - - - EmptyState + diff --git a/plugins/kubernetes/src/Router.tsx b/plugins/kubernetes/src/Router.tsx index fd3a4bd0ce..bd8fc09edc 100644 --- a/plugins/kubernetes/src/Router.tsx +++ b/plugins/kubernetes/src/Router.tsx @@ -18,7 +18,7 @@ import React from 'react'; import { Entity } from '@backstage/catalog-model'; import { useEntity } from '@backstage/plugin-catalog-react'; import { Route, Routes } from 'react-router-dom'; -import { KubernetesContent } from './components/KubernetesContent'; +import { KubernetesContent } from './KubernetesContent'; import { Button } from '@material-ui/core'; import { MissingAnnotationEmptyState } from '@backstage/core-components'; diff --git a/plugins/kubernetes/src/assets/emptystate.svg b/plugins/kubernetes/src/assets/emptystate.svg deleted file mode 100644 index 8a0490727f..0000000000 --- a/plugins/kubernetes/src/assets/emptystate.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/plugins/kubernetes/src/components/IngressesAccordions/index.ts b/plugins/kubernetes/src/components/IngressesAccordions/index.ts deleted file mode 100644 index 8e7f103e42..0000000000 --- a/plugins/kubernetes/src/components/IngressesAccordions/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2020 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 { IngressesAccordions } from './IngressesAccordions'; diff --git a/plugins/kubernetes/src/components/ServicesAccordions/index.ts b/plugins/kubernetes/src/components/ServicesAccordions/index.ts deleted file mode 100644 index 04fee9caca..0000000000 --- a/plugins/kubernetes/src/components/ServicesAccordions/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2020 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 { ServicesAccordions } from './ServicesAccordions'; diff --git a/plugins/kubernetes/src/index.ts b/plugins/kubernetes/src/index.ts index 616caaef62..3651a861fc 100644 --- a/plugins/kubernetes/src/index.ts +++ b/plugins/kubernetes/src/index.ts @@ -27,10 +27,5 @@ export { } from './plugin'; export type { EntityKubernetesContentProps } from './plugin'; export { Router, isKubernetesAvailable } from './Router'; -export * from './api'; -export * from './kubernetes-auth-provider'; -export * from './utils/clusterLinks'; -export * from './components'; -export * from './error-detection'; -export * from './hooks'; -export * from './types'; +// TODO remove this re-export as a breaking change after a couple of releases +export * from '@backstage/plugin-kubernetes-react'; diff --git a/plugins/kubernetes/src/kubernetes-auth-provider/index.ts b/plugins/kubernetes/src/kubernetes-auth-provider/index.ts deleted file mode 100644 index 23197321f6..0000000000 --- a/plugins/kubernetes/src/kubernetes-auth-provider/index.ts +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2020 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 { kubernetesAuthProvidersApiRef } from './types'; -export type { KubernetesAuthProvidersApi } from './types'; -export { KubernetesAuthProviders } from './KubernetesAuthProviders'; -export { GoogleKubernetesAuthProvider } from './GoogleKubernetesAuthProvider'; -export { ServerSideKubernetesAuthProvider } from './ServerSideAuthProvider'; diff --git a/plugins/kubernetes/src/plugin.ts b/plugins/kubernetes/src/plugin.ts index 02c7bfd2d6..ac55dbbf23 100644 --- a/plugins/kubernetes/src/plugin.ts +++ b/plugins/kubernetes/src/plugin.ts @@ -13,10 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { KubernetesBackendClient } from './api/KubernetesBackendClient'; -import { kubernetesApiRef, kubernetesProxyApiRef } from './api/types'; -import { kubernetesAuthProvidersApiRef } from './kubernetes-auth-provider/types'; -import { KubernetesAuthProviders } from './kubernetes-auth-provider/KubernetesAuthProviders'; +import { + KubernetesBackendClient, + kubernetesApiRef, + kubernetesProxyApiRef, + kubernetesAuthProvidersApiRef, + KubernetesAuthProviders, + KubernetesProxyClient, +} from '@backstage/plugin-kubernetes-react'; import { createApiFactory, createPlugin, @@ -30,7 +34,6 @@ import { oneloginAuthApiRef, createRoutableExtension, } from '@backstage/core-plugin-api'; -import { KubernetesProxyClient } from './api'; export const rootCatalogKubernetesRouteRef = createRouteRef({ id: 'kubernetes', diff --git a/plugins/kubernetes/src/types/types.ts b/plugins/kubernetes/src/types/types.ts deleted file mode 100644 index f15c4f335a..0000000000 --- a/plugins/kubernetes/src/types/types.ts +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2020 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 type { JsonObject } from '@backstage/types'; -import { - V1Deployment, - V1Pod, - V1ReplicaSet, - V1HorizontalPodAutoscaler, - V1Service, - V1ConfigMap, - V1Ingress, - V1Job, - V1CronJob, - V1StatefulSet, -} from '@kubernetes/client-node'; - -export interface DeploymentResources { - pods: V1Pod[]; - replicaSets: V1ReplicaSet[]; - deployments: V1Deployment[]; - horizontalPodAutoscalers: V1HorizontalPodAutoscaler[]; -} - -export interface GroupedResponses extends DeploymentResources { - services: V1Service[]; - configMaps: V1ConfigMap[]; - ingresses: V1Ingress[]; - jobs: V1Job[]; - cronJobs: V1CronJob[]; - customResources: any[]; - statefulsets: V1StatefulSet[]; -} - -export interface ClusterLinksFormatterOptions { - dashboardUrl?: URL; - dashboardParameters?: JsonObject; - object: any; - kind: string; -} - -export type ClusterLinksFormatter = ( - options: ClusterLinksFormatterOptions, -) => URL; diff --git a/yarn.lock b/yarn.lock index c1887a4ea0..29a232840d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7636,8 +7636,56 @@ __metadata: dependencies: "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" + "@backstage/core-app-api": "workspace:^" + "@backstage/core-plugin-api": "workspace:^" + "@backstage/errors": "workspace:^" "@backstage/plugin-permission-common": "workspace:^" + "@backstage/test-utils": "workspace:^" + "@backstage/types": "workspace:^" "@kubernetes/client-node": 0.18.1 + kubernetes-models: ^4.3.1 + lodash: ^4.17.21 + luxon: ^3.0.0 + msw: ^1.3.1 + languageName: unknown + linkType: soft + +"@backstage/plugin-kubernetes-react@workspace:^, @backstage/plugin-kubernetes-react@workspace:plugins/kubernetes-react": + version: 0.0.0-use.local + resolution: "@backstage/plugin-kubernetes-react@workspace:plugins/kubernetes-react" + dependencies: + "@backstage/catalog-model": "workspace:^" + "@backstage/cli": "workspace:^" + "@backstage/core-app-api": "workspace:^" + "@backstage/core-components": "workspace:^" + "@backstage/core-plugin-api": "workspace:^" + "@backstage/errors": "workspace:^" + "@backstage/plugin-kubernetes-common": "workspace:^" + "@backstage/test-utils": "workspace:^" + "@backstage/types": "workspace:^" + "@kubernetes-models/apimachinery": ^1.1.0 + "@kubernetes-models/base": ^4.0.1 + "@kubernetes/client-node": ^0.19.0 + "@material-ui/core": ^4.9.13 + "@material-ui/icons": ^4.11.3 + "@material-ui/lab": ^4.0.0-alpha.61 + "@testing-library/jest-dom": ^5.10.1 + "@testing-library/react": ^12.1.3 + "@testing-library/react-hooks": ^8.0.1 + "@types/react": ^16.13.1 || ^17.0.0 + cronstrue: ^2.32.0 + jest-websocket-mock: ^2.5.0 + js-yaml: ^4.1.0 + kubernetes-models: ^4.3.1 + lodash: ^4.17.21 + luxon: ^3.0.0 + msw: ^1.3.1 + react-use: ^17.4.0 + xterm: ^5.3.0 + xterm-addon-attach: ^0.9.0 + xterm-addon-fit: ^0.8.0 + peerDependencies: + react: ^16.13.1 || ^17.0.0 languageName: unknown linkType: soft @@ -7655,6 +7703,7 @@ __metadata: "@backstage/errors": "workspace:^" "@backstage/plugin-catalog-react": "workspace:^" "@backstage/plugin-kubernetes-common": "workspace:^" + "@backstage/plugin-kubernetes-react": "workspace:^" "@backstage/test-utils": "workspace:^" "@backstage/theme": "workspace:^" "@backstage/types": "workspace:^" @@ -12776,6 +12825,32 @@ __metadata: languageName: node linkType: hard +"@kubernetes/client-node@npm:^0.19.0": + version: 0.19.0 + resolution: "@kubernetes/client-node@npm:0.19.0" + dependencies: + "@types/js-yaml": ^4.0.1 + "@types/node": ^20.1.1 + "@types/request": ^2.47.1 + "@types/ws": ^8.5.3 + byline: ^5.0.0 + isomorphic-ws: ^5.0.0 + js-yaml: ^4.1.0 + jsonpath-plus: ^7.2.0 + openid-client: ^5.3.0 + request: ^2.88.0 + rfc4648: ^1.3.0 + stream-buffers: ^3.0.2 + tar: ^6.1.11 + tslib: ^2.4.1 + ws: ^8.11.0 + dependenciesMeta: + openid-client: + optional: true + checksum: d29ccfb562ac51a81f74de570eb832d150be6b73ba887ae1be682df9a34c3ab846d4d4ba74f0a9f0e0ce4da573f949ba712115e1d0513148cdf683a22d729e7f + languageName: node + linkType: hard + "@leichtgewicht/ip-codec@npm:^2.0.1": version: 2.0.3 resolution: "@leichtgewicht/ip-codec@npm:2.0.3" @@ -12949,7 +13024,7 @@ __metadata: languageName: node linkType: hard -"@material-ui/icons@npm:^4.11.2, @material-ui/icons@npm:^4.9.1": +"@material-ui/icons@npm:^4.11.2, @material-ui/icons@npm:^4.11.3, @material-ui/icons@npm:^4.9.1": version: 4.11.3 resolution: "@material-ui/icons@npm:4.11.3" dependencies: @@ -13008,7 +13083,7 @@ __metadata: languageName: node linkType: hard -"@material-ui/lab@npm:4.0.0-alpha.61, @material-ui/lab@npm:^4.0.0-alpha.57, @material-ui/lab@npm:^4.0.0-alpha.60": +"@material-ui/lab@npm:4.0.0-alpha.61, @material-ui/lab@npm:^4.0.0-alpha.57, @material-ui/lab@npm:^4.0.0-alpha.60, @material-ui/lab@npm:^4.0.0-alpha.61": version: 4.0.0-alpha.61 resolution: "@material-ui/lab@npm:4.0.0-alpha.61" dependencies: @@ -17866,10 +17941,10 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:*, @types/node@npm:>=12.12.47, @types/node@npm:>=13.7.0": - version: 20.6.3 - resolution: "@types/node@npm:20.6.3" - checksum: 444a6f1f41cfa8d3e20ce0108e6e43960fb2ae0e481f233bb1c14d6252aa63a92e021de561cd317d9fdb411688f871065f40175a1f18763282dee2613a08f8a3 +"@types/node@npm:*, @types/node@npm:>=12.12.47, @types/node@npm:>=13.7.0, @types/node@npm:^20.1.1": + version: 20.6.5 + resolution: "@types/node@npm:20.6.5" + checksum: b849e849cf7631458a65c5019c81962028e306d8c4455a48422277b240f5a7eb8a1f1dafa60306bd4c773b77263bb8b05c074b1026e868bd137bb2022cf63ea2 languageName: node linkType: hard @@ -22570,12 +22645,12 @@ __metadata: languageName: node linkType: hard -"cronstrue@npm:^2.2.0": - version: 2.31.0 - resolution: "cronstrue@npm:2.31.0" +"cronstrue@npm:^2.2.0, cronstrue@npm:^2.32.0": + version: 2.32.0 + resolution: "cronstrue@npm:2.32.0" bin: cronstrue: bin/cli.js - checksum: 8001433f65751ccd471497be14924dfecd6b91992d615ec7de1fec978792e4a3ab977d05874bea7b6a478dc786ea775554735126c79c8bbe3c94535f20ebebab + checksum: a0925e256583122792fe2f3b92cd49b954ab3e4466c7569a9148b9981db8a389faca139d4eb215142e7b67438a5562219956c56041ed0b8b046b798e72a357a8 languageName: node linkType: hard @@ -29833,7 +29908,7 @@ __metadata: languageName: node linkType: hard -"jest-websocket-mock@npm:^2.4.1": +"jest-websocket-mock@npm:^2.4.1, jest-websocket-mock@npm:^2.5.0": version: 2.5.0 resolution: "jest-websocket-mock@npm:2.5.0" dependencies: @@ -30887,7 +30962,7 @@ __metadata: languageName: node linkType: hard -"kubernetes-models@npm:^4.1.0": +"kubernetes-models@npm:^4.1.0, kubernetes-models@npm:^4.3.1": version: 4.3.1 resolution: "kubernetes-models@npm:4.3.1" dependencies: @@ -33053,7 +33128,7 @@ __metadata: languageName: node linkType: hard -"msw@npm:^1.0.0, msw@npm:^1.0.1, msw@npm:^1.2.1, msw@npm:^1.2.3": +"msw@npm:^1.0.0, msw@npm:^1.0.1, msw@npm:^1.2.1, msw@npm:^1.2.3, msw@npm:^1.3.1": version: 1.3.1 resolution: "msw@npm:1.3.1" dependencies: @@ -42703,6 +42778,15 @@ __metadata: languageName: node linkType: hard +"xterm-addon-attach@npm:^0.9.0": + version: 0.9.0 + resolution: "xterm-addon-attach@npm:0.9.0" + peerDependencies: + xterm: ^5.0.0 + checksum: 70e5d3ecf139c04fae13c644b79c33858ef1a6e28dfe78f91dad3e34f5a155579029b87e91d1d016575acaf17f74e6c59402bde4bcff03461595bea0870f1ec1 + languageName: node + linkType: hard + "xterm-addon-fit@npm:^0.7.0": version: 0.7.0 resolution: "xterm-addon-fit@npm:0.7.0" @@ -42712,10 +42796,19 @@ __metadata: languageName: node linkType: hard -"xterm@npm:^5.2.1": - version: 5.2.1 - resolution: "xterm@npm:5.2.1" - checksum: 3a9de30e772c7ae30895ec97fcfb3b0906429c5ea0cddf8948e8e30301385f82e467c6e6aca28ae50a48300ce795381d83fe35b4e17886ab4a1357054a15f68f +"xterm-addon-fit@npm:^0.8.0": + version: 0.8.0 + resolution: "xterm-addon-fit@npm:0.8.0" + peerDependencies: + xterm: ^5.0.0 + checksum: 5af2041b442f7c804eda2e6f62e3b68b5159b0ae6bd96e2aa8d85b26441df57291cbfed653d1196d4af5d9b94bfc39993df8b409a25c35e0d36bdaf6f5cdfe5f + languageName: node + linkType: hard + +"xterm@npm:^5.2.1, xterm@npm:^5.3.0": + version: 5.3.0 + resolution: "xterm@npm:5.3.0" + checksum: 1bdfdfe4cae4412128376180d85e476b43fb021cdd1114b18acad821c9ea44b5b600e0d88febf2b3572f38fad7741e5161ce0178a44369617cf937222cc6e011 languageName: node linkType: hard From ade908a100185d43b8ba800a89e629d20bd026ac Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 26 Sep 2023 21:32:15 -0300 Subject: [PATCH 091/110] Add Cielo to ADOPTERS.md Signed-off-by: Alex --- ADOPTERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ADOPTERS.md b/ADOPTERS.md index 0d5b9fba59..958d24b968 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -260,3 +260,4 @@ _You can do this by using the [Adopter form](https://info.backstage.spotify.com/ | [Localiza&Co](https://www.localiza.com/) | [Augusto Amormino](https://github.com/augustoamormino), [Jonas Soares](https://github.com/jonaopower), [Alexandre Amormino](https://github.com/alexandreamormino), [Greg Almeida](https://github.com/sephh) | We're excited to announce our adoption of Backstage as our Internal Developer Portal! Our mission is to elevate the Developer Experience by streaming information access. Backstage will serve as the ultimate hub for developer resources, including documentation, tools, software insights, and metrics. Through Backstage, we're simplifying processes, offering software templates to empowered and efficient development journey, enhancing self-service capabilities with the embedded all best practices. | | [V2 Digital](https://v2.digital) | [Joe Patterson](https://github.com/jrwpatterson)| We will be using it to be a corporate dashboard plus our software catalog. | | [AppsFlyer](https://www.appsflyer.com/) | [Shahar Shmaram](https://github.com/shmaram) | Internal Developer Portal, a catalog of all company resources, custom providers and processors, scaffolder for generating new resources. +| [Cielo](https://www.cielo.com.br) | [@Alex Silva](https://github.com/narokwq) | We are using as our Internal Developer Portal, it provides developers with the resources, information, and tools they need to build high-quality applications and adhere to organizational standards and security practices. | From bbfa6526f9cdcc58bf32b0eae54bc073c192e938 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 27 Sep 2023 07:41:55 +0000 Subject: [PATCH 092/110] chore(deps): update dependency @types/node-forge to v1.3.6 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 54d0650ad7..48e57bb072 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17933,11 +17933,11 @@ __metadata: linkType: hard "@types/node-forge@npm:^1.3.0": - version: 1.3.5 - resolution: "@types/node-forge@npm:1.3.5" + version: 1.3.6 + resolution: "@types/node-forge@npm:1.3.6" dependencies: "@types/node": "*" - checksum: b93dae2639ab166d8703567285538f14a53fbe9199b02c1e3752d147260be4a8be5257246558a81fc3eee3c5880704039a6aa22c4415aeb06758aad0391ac39c + checksum: 5fe97ce83937c51215a52eb8c9d5c4458abbca2b3cfd91a65142f20fd4a2830ed10ab1a8c860efc55ff36553f939a75c4a6d5c243ed6e24e55a005c9bddeaf43 languageName: node linkType: hard From f18fdc9a43bea25da353267f66050dacd36c0808 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 27 Sep 2023 07:50:26 +0000 Subject: [PATCH 093/110] chore(deps): update dependency @types/nunjucks to v3.2.4 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 86e1eb70c1..0288cdebd4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17991,9 +17991,9 @@ __metadata: linkType: hard "@types/nunjucks@npm:^3.1.4": - version: 3.2.3 - resolution: "@types/nunjucks@npm:3.2.3" - checksum: f4263a39f0bafb701fe75a088cf2100f0fe717ab29c53d13eb60fea77e945f8cfdabfb84bd6ce85fd11586f90aa36539cf5bd489166edcf56a189a0407d481a2 + version: 3.2.4 + resolution: "@types/nunjucks@npm:3.2.4" + checksum: d154c6cc98320b6b9f48892eb4238f961b0196e24eb98252f9dceaa0b17bf70cd480a11d4ffda9f419d2570abf6d96524ebd3193b101f0fcf73c65af3e56d064 languageName: node linkType: hard From b777bc45da4f12a756e2c4b243aeef1e1df37f89 Mon Sep 17 00:00:00 2001 From: Jonathan Mezach Date: Wed, 27 Sep 2023 10:05:14 +0200 Subject: [PATCH 094/110] Adding myself as a codeowner for the - New Relic Browser Analytics plugin - Octopus Deploy plugin Signed-off-by: Jonathan Mezach --- .github/CODEOWNERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index a0ba1163f3..cb8101e1b1 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -21,6 +21,7 @@ yarn.lock @backstage/maintainers @backst /plugins/azure-devops @backstage/maintainers @backstage/reviewers @awanlin /plugins/azure-devops-backend @backstage/maintainers @backstage/reviewers @awanlin /plugins/azure-devops-common @backstage/maintainers @backstage/reviewers @awanlin +/plugins/analytics-module-newrelic-browser @backstage/maintainers @backstage/reviewers @jmezach /plugins/bitbucket-cloud-common @backstage/maintainers @backstage/reviewers @pjungermann /plugins/bitrise @backstage/maintainers @backstage/reviewers @backstage/sda-se-reviewers /plugins/catalog @backstage/maintainers @backstage/reviewers @backstage/catalog-maintainers @@ -62,6 +63,7 @@ yarn.lock @backstage/maintainers @backst /plugins/linguist @backstage/maintainers @backstage/reviewers @awanlin /plugins/linguist-backend @backstage/maintainers @backstage/reviewers @awanlin /plugins/linguist-common @backstage/maintainers @backstage/reviewers @awanlin +/plugins/octopus-deploy @backstage/maintainers @backstage/reviewers @jmezach /plugins/permission-* @backstage/permission-maintainers /plugins/playlist @backstage/maintainers @backstage/reviewers @kuangp /plugins/playlist-* @backstage/maintainers @backstage/reviewers @kuangp From fd7072f8582810d691932e94c97ff688b5a66445 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 27 Sep 2023 09:15:45 +0000 Subject: [PATCH 095/110] chore(deps): update dependency @types/passport-auth0 to v1.0.7 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 86e1eb70c1..0e38e39234 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18021,12 +18021,12 @@ __metadata: linkType: hard "@types/passport-auth0@npm:^1.0.5": - version: 1.0.5 - resolution: "@types/passport-auth0@npm:1.0.5" + version: 1.0.7 + resolution: "@types/passport-auth0@npm:1.0.7" dependencies: "@types/express": "*" "@types/passport": "*" - checksum: b86b69a182864cae6877c0f16a1d62e24a394dc9cde8e7285a29aef89d52fbb555b899e061157bfd52420dcbccd6fd9b189155e5367a22763b0b2813cbb28354 + checksum: 75b17c3424054a8b0238905088a7c34efab771a0bccc5ce0270d5c6f238ba859fb7354531c0df4f39e7b2c28f10090f9c260ffc42773211fc216a9acbf11170a languageName: node linkType: hard From e2cc718bb5499b7fb567f3e90ed0a928d9efadff Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 27 Sep 2023 09:16:17 +0000 Subject: [PATCH 096/110] chore(deps): update dependency @types/passport-github2 to v1.2.6 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 86e1eb70c1..40532363ee 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18031,13 +18031,13 @@ __metadata: linkType: hard "@types/passport-github2@npm:^1.2.4": - version: 1.2.5 - resolution: "@types/passport-github2@npm:1.2.5" + version: 1.2.6 + resolution: "@types/passport-github2@npm:1.2.6" dependencies: "@types/express": "*" "@types/passport": "*" "@types/passport-oauth2": "*" - checksum: a4f1851edb91a2502136b7e76dd10fd3c52aebec938ff21ffa2ade40b1f62d0e7f65991c80589f5cfa40b6cba04bf0b8ea46db6942975bf5918fa4690f681235 + checksum: 72d1c8bc335d0d7f329372ac8bc7edb22c8bea151d4438d876036b6b768f4d12c8de305abbc25b650f373b902bae250008cb185074d2d78da49d15e981208d81 languageName: node linkType: hard From 81f2ffbbb9671b2b66c4ec4b87035aafb53bc65a Mon Sep 17 00:00:00 2001 From: Ringo De Smet Date: Wed, 27 Sep 2023 11:35:40 +0200 Subject: [PATCH 097/110] Register Pulumi plugin Signed-off-by: Ringo De Smet --- microsite/data/plugins/pulumi.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 microsite/data/plugins/pulumi.yaml diff --git a/microsite/data/plugins/pulumi.yaml b/microsite/data/plugins/pulumi.yaml new file mode 100644 index 0000000000..4724f00f58 --- /dev/null +++ b/microsite/data/plugins/pulumi.yaml @@ -0,0 +1,10 @@ +--- +title: Pulumi +author: pulumi.com +authorUrl: https://www.pulumi.com +category: Infrastructure +description: View Pulumi stack information in Backstage. +documentation: https://github.com/pulumi/pulumi-backstage-plugin +iconUrl: https://www.pulumi.com/logos/brand/avatar-on-white.png +npmPackageName: '@pulumi/backstage-plugin-pulumi' +addedDate: '2023-09-27' From 2c5a5cf6edf32847827458a331d3fc41be1e3b2e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 27 Sep 2023 11:32:22 +0000 Subject: [PATCH 098/110] chore(deps): update dependency @types/marked to v4.3.2 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 86e1eb70c1..d5433077b6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17821,9 +17821,9 @@ __metadata: linkType: hard "@types/marked@npm:^4.0.0": - version: 4.3.1 - resolution: "@types/marked@npm:4.3.1" - checksum: eb6891b925d53ea53057f088b28f9232016499e62639cbb4a67f7d34f288ec6a8e40aae4836dbd06bd0fc3c541fca1175cd50d9e8d405547b6be7b7781e6a2a5 + version: 4.3.2 + resolution: "@types/marked@npm:4.3.2" + checksum: c1107079d6c368dd60a668a41aa2101d006cad404b6eb4af6723d419dc869b278928fb769825f11d0d311a8cf437428992729c8a47253b6a3894a6326b1ee4d9 languageName: node linkType: hard From fce94934eb8923d5912ee37e1693ef004242f5dc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 27 Sep 2023 11:32:54 +0000 Subject: [PATCH 099/110] chore(deps): update dependency @types/mime-types to v2.1.2 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 86e1eb70c1..27da5650a3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17844,9 +17844,9 @@ __metadata: linkType: hard "@types/mime-types@npm:^2.1.0": - version: 2.1.1 - resolution: "@types/mime-types@npm:2.1.1" - checksum: 106b5d556add46446a579ad25ff15d6b421851790d887edcad558c90c1e64b1defc72bfbaf4b08f208916e21d9cc45cdb951d77be51268b18221544cfe054a3c + version: 2.1.2 + resolution: "@types/mime-types@npm:2.1.2" + checksum: 9e3c78f1c63211e0450901212566a046da68d4438a5e543333ec9b0be3259bd5d01532734dc51ead40104889b98d12c7663b65212a318aafad3e34c98204e9e1 languageName: node linkType: hard From c24cd93ef6d6ee821943d50e969459a2fcef393d Mon Sep 17 00:00:00 2001 From: Ringo De Smet Date: Wed, 27 Sep 2023 13:49:49 +0200 Subject: [PATCH 100/110] Update microsite/data/plugins/pulumi.yaml Co-authored-by: Philipp Hugenroth Signed-off-by: Ringo De Smet --- microsite/data/plugins/pulumi.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/microsite/data/plugins/pulumi.yaml b/microsite/data/plugins/pulumi.yaml index 4724f00f58..ea97bcdef3 100644 --- a/microsite/data/plugins/pulumi.yaml +++ b/microsite/data/plugins/pulumi.yaml @@ -1,6 +1,6 @@ --- title: Pulumi -author: pulumi.com +author: Pulumi authorUrl: https://www.pulumi.com category: Infrastructure description: View Pulumi stack information in Backstage. From 149a500278878cd0767ceb70dd45230587b3c561 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 27 Sep 2023 12:27:24 +0000 Subject: [PATCH 101/110] chore(deps): update dependency @types/minimist to v1.2.3 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 86e1eb70c1..242918d863 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17872,9 +17872,9 @@ __metadata: linkType: hard "@types/minimist@npm:^1.2.0": - version: 1.2.2 - resolution: "@types/minimist@npm:1.2.2" - checksum: b8da83c66eb4aac0440e64674b19564d9d86c80ae273144db9681e5eeff66f238ade9515f5006ffbfa955ceff8b89ad2bd8ec577d7caee74ba101431fb07045d + version: 1.2.3 + resolution: "@types/minimist@npm:1.2.3" + checksum: 666ea4f8c39dcbdfbc3171fe6b3902157c845cc9cb8cee33c10deb706cda5e0cc80f98ace2d6d29f6774b0dc21180c96cd73c592a1cbefe04777247c7ba0e84b languageName: node linkType: hard From 1b4d43e4f3ecb1ebbf947a23a515c9d048af124b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 27 Sep 2023 12:27:59 +0000 Subject: [PATCH 102/110] chore(deps): update dependency @types/mock-fs to v4.13.2 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 86e1eb70c1..7037587a67 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17879,11 +17879,11 @@ __metadata: linkType: hard "@types/mock-fs@npm:^4.10.0, @types/mock-fs@npm:^4.13.0": - version: 4.13.1 - resolution: "@types/mock-fs@npm:4.13.1" + version: 4.13.2 + resolution: "@types/mock-fs@npm:4.13.2" dependencies: "@types/node": "*" - checksum: a5fcf8212daa270e6aa560019a4bd28a66e6fa49c55c1373746d5894f4aa1aafa5588335194953cf014de3c77df6be67a041fb6638ead7124307370985880b6c + checksum: 726975ae51f7b4068bb059c633ae28a1d85595d3036c235d3f9c9dc3a9c519dc6b811713af1b686807e80a484a6ec47a742a11b4ada32a6e74eee6538a9f4658 languageName: node linkType: hard From 36292f085411c91bdbabc0705efad4a13e54e939 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 27 Sep 2023 14:58:30 +0000 Subject: [PATCH 103/110] chore(deps): update dependency @types/morgan to v1.9.6 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 9b10f4f99a..930378e7e0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17888,11 +17888,11 @@ __metadata: linkType: hard "@types/morgan@npm:^1.9.0": - version: 1.9.5 - resolution: "@types/morgan@npm:1.9.5" + version: 1.9.6 + resolution: "@types/morgan@npm:1.9.6" dependencies: "@types/node": "*" - checksum: f98deb4c7f2ad6049ad34ed7b0f0d427546bdf2358011070af9d597de1b0a03b38cc10cfe65ef2e7673e569c384303d949e76df701acefe288d547f614142973 + checksum: 6525248325a74342f929c958be69c0840c8f3a288e003a8904319cae92e531f17a8aa2700701e66775adcca7f9506dd630fec2f95dc04a3e73add04fde42aab8 languageName: node linkType: hard From 2fd3103fc84da27d9266e0b9b6aa20565722d294 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 27 Sep 2023 14:59:02 +0000 Subject: [PATCH 104/110] chore(deps): update dependency @types/passport-google-oauth20 to v2.0.12 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 9b10f4f99a..0f75161ae9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18042,13 +18042,13 @@ __metadata: linkType: hard "@types/passport-google-oauth20@npm:^2.0.3": - version: 2.0.11 - resolution: "@types/passport-google-oauth20@npm:2.0.11" + version: 2.0.12 + resolution: "@types/passport-google-oauth20@npm:2.0.12" dependencies: "@types/express": "*" "@types/passport": "*" "@types/passport-oauth2": "*" - checksum: 5e87a0bf40d77ce863dbcea4ae1cd6bccc663282593c9b6ce83b0e2d5d6c56ed9dc0275a04f5d81832f03b3a477fd47d17fd9b3ee22ceb69ca445ab0b0d326d7 + checksum: e73fff5b7e3191ab1a3633b05b4463d656ef658fe0612bc33517a1df81c8a1f019c91dcbd244233320f9eb133892b589dcb6a6348082e85e45aa5c6ed034d191 languageName: node linkType: hard From 2561949c4b96ad7059cf84b0a3341a5fad1dba73 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 27 Sep 2023 16:13:38 +0000 Subject: [PATCH 105/110] chore(deps): update dependency @types/passport-microsoft to v1.0.1 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 9b10f4f99a..5f6335b243 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18053,11 +18053,11 @@ __metadata: linkType: hard "@types/passport-microsoft@npm:^1.0.0": - version: 1.0.0 - resolution: "@types/passport-microsoft@npm:1.0.0" + version: 1.0.1 + resolution: "@types/passport-microsoft@npm:1.0.1" dependencies: "@types/passport-oauth2": "*" - checksum: d7c8b439b18cddcf707ea0c575748ecb344b6fb3c78a847aaad83246abf081c8b485efa86a3788cd5f49f4ca84a1444d813697a433fab9d04f35fb67d628cb23 + checksum: eec44ee6e14448b89434503a438021df6738513fa705b42a6d979a6b817ce89f939996a5d30707a64bca700dbc7c6ae52f1010ad2e986bb7ccd9f935d2114c9e languageName: node linkType: hard From 40203692c439a9729249c4f3081abfe5abd14621 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 27 Sep 2023 16:14:09 +0000 Subject: [PATCH 106/110] chore(deps): update dependency @types/passport-saml to v1.1.4 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 9b10f4f99a..6cc3ccf862 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18073,12 +18073,12 @@ __metadata: linkType: hard "@types/passport-saml@npm:^1.1.3": - version: 1.1.3 - resolution: "@types/passport-saml@npm:1.1.3" + version: 1.1.4 + resolution: "@types/passport-saml@npm:1.1.4" dependencies: "@types/express": "*" "@types/passport": "*" - checksum: 1d0abc04b1f19c043f9dd311248d3d98b00b311ed6d2cfa6cb17ef0954d0b403de4ccca4f1be192cbfda92105eb799c7963da6f39e4542ca254b06d5c467ed4a + checksum: 2a71d64c72b0f6cf4cafcc21138f5c925cc9bc375a0dd7ece664e8b1254dd4a704566632bafa3e16032821a7f010de4023169589b643a3b952709cde228a8c8c languageName: node linkType: hard From c804e45743827a67719e5c198329c54b66a92b8c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 27 Sep 2023 17:13:02 +0000 Subject: [PATCH 107/110] chore(deps): update dependency @types/passport-strategy to v0.2.36 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 604a9de5b3..6dda2d5b79 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18083,12 +18083,12 @@ __metadata: linkType: hard "@types/passport-strategy@npm:^0.2.35": - version: 0.2.35 - resolution: "@types/passport-strategy@npm:0.2.35" + version: 0.2.36 + resolution: "@types/passport-strategy@npm:0.2.36" dependencies: "@types/express": "*" "@types/passport": "*" - checksum: e5949063ad8977ce1f7cf2a5df6bc379c4d43a959c9946bfed6570ef379c6c12d1713212a29b3b5aafc631c5ebe9bfe082116f3e75ca1bf45d79dd889671532d + checksum: 7f626eb6a12110c1ce64dd5d5181fc0795e77d60123872e33f6fa1c02a2a19451207eaf03543232241a1d70bfe0318f2ffeef88f6309d7cbaa43d2bf6ec1d1e8 languageName: node linkType: hard From 2934320c1ffd3072c5f5256b0cefba75a81870b9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 27 Sep 2023 17:13:33 +0000 Subject: [PATCH 108/110] chore(deps): update dependency @types/pg to v8.10.3 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 604a9de5b3..4c5d3df522 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18102,13 +18102,13 @@ __metadata: linkType: hard "@types/pg@npm:^8.6.6": - version: 8.10.2 - resolution: "@types/pg@npm:8.10.2" + version: 8.10.3 + resolution: "@types/pg@npm:8.10.3" dependencies: "@types/node": "*" pg-protocol: "*" pg-types: ^4.0.1 - checksum: 49da89f64cec1bd12a3fbc0c72b17d685c2fee579726a529f62fcab395dbc5696d80455073409947a577164b3c53a90181a331e4a5d9357679f724d4ce37f4b9 + checksum: 05a12be3f18cc67728e3aee5a7426f065351ca991e351d2e7a0562c5d9063425d67fe88fd35108834e0fa1f5624032fefbf371cf8f3cc47230a666aa953425b9 languageName: node linkType: hard From 4757e81c04bbda94d4507bb8fd1770e2188d1771 Mon Sep 17 00:00:00 2001 From: Lee Mills Date: Thu, 28 Sep 2023 10:32:14 +0100 Subject: [PATCH 109/110] Transfering ownership of Spotify's internal instance of Bacsktage to Helen Greul Signed-off-by: Lee Mills --- ADOPTERS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ADOPTERS.md b/ADOPTERS.md index 958d24b968..f03ed8d270 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -5,7 +5,7 @@ _You can do this by using the [Adopter form](https://info.backstage.spotify.com/ | Organization | Contact | Description of Use | |-----------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Spotify](https://www.spotify.com) | [@leemills83](https://github.com/leemills83) | Main interface towards all of Spotify's infrastructure and technical documentation. | +| [Spotify](https://www.spotify.com) | [@helengreul](https://github.com/helengreul) | Main interface towards all of Spotify's infrastructure and technical documentation. | | [bol.com](https://www.bol.com) | [@acierto](https://github.com/acierto), [@clanghout](https://github.com/clanghout) | Initial work being done to unify platform tooling. | | [DFDS](https://www.dfds.com) | [@carlsendk](https://github.com/carlsendk) | V2 self-service platform. | | [Roadie](https://roadie.io) | [@dtuite](https://github.com/dtuite) | Hosted, managed Backstage with easy set-up | From 086b5ccabcc8512aff95c176d68a04341a49651b Mon Sep 17 00:00:00 2001 From: Federico Morreale Date: Thu, 28 Sep 2023 11:44:56 +0200 Subject: [PATCH 110/110] fix: action buttons are now responsive Signed-off-by: Federico Morreale --- microsite/src/components/contentBlock/contentBlock.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/microsite/src/components/contentBlock/contentBlock.tsx b/microsite/src/components/contentBlock/contentBlock.tsx index 983f684927..5c3e47fe74 100644 --- a/microsite/src/components/contentBlock/contentBlock.tsx +++ b/microsite/src/components/contentBlock/contentBlock.tsx @@ -37,7 +37,14 @@ export const ContentBlock = ({ {children && React.isValidElement(children) ? children :

{children}

} {actionButtons && ( -
+
{actionButtons.map(({ link, label }, index) => (