From eeb2c90a38159adccb25de83b292954c45b1350e Mon Sep 17 00:00:00 2001 From: Bret Hubbard Date: Wed, 30 Mar 2022 10:19:42 -0600 Subject: [PATCH 01/58] catalog-backend: extract getDocumentText to improve testability Co-authored-by: Jason Nguyen Signed-off-by: Bret Hubbard --- .../search/DefaultCatalogCollatorFactory.ts | 27 +----- .../catalog-backend/src/search/util.test.ts | 95 +++++++++++++++++++ plugins/catalog-backend/src/search/util.ts | 35 +++++++ 3 files changed, 133 insertions(+), 24 deletions(-) create mode 100644 plugins/catalog-backend/src/search/util.test.ts create mode 100644 plugins/catalog-backend/src/search/util.ts diff --git a/plugins/catalog-backend/src/search/DefaultCatalogCollatorFactory.ts b/plugins/catalog-backend/src/search/DefaultCatalogCollatorFactory.ts index 98bcfcd8d4..cf082c271c 100644 --- a/plugins/catalog-backend/src/search/DefaultCatalogCollatorFactory.ts +++ b/plugins/catalog-backend/src/search/DefaultCatalogCollatorFactory.ts @@ -23,11 +23,7 @@ import { CatalogClient, GetEntitiesRequest, } from '@backstage/catalog-client'; -import { - Entity, - stringifyEntityRef, - UserEntity, -} from '@backstage/catalog-model'; +import { stringifyEntityRef } from '@backstage/catalog-model'; import { Config } from '@backstage/config'; import { DocumentCollatorFactory } from '@backstage/plugin-search-common'; import { @@ -36,6 +32,7 @@ import { } from '@backstage/plugin-catalog-common'; import { Permission } from '@backstage/plugin-permission-common'; import { Readable } from 'stream'; +import { getDocumentText } from './util'; /** @public */ export type DefaultCatalogCollatorFactoryOptions = { @@ -100,24 +97,6 @@ export class DefaultCatalogCollatorFactory implements DocumentCollatorFactory { return formatted.toLowerCase(); } - private isUserEntity(entity: Entity): entity is UserEntity { - return entity.kind.toLocaleUpperCase('en-US') === 'USER'; - } - - private getDocumentText(entity: Entity): string { - let documentText = entity.metadata.description || ''; - if (this.isUserEntity(entity)) { - if (entity.spec?.profile?.displayName && documentText) { - // combine displayName and description - const displayName = entity.spec?.profile?.displayName; - documentText = displayName.concat(' : ', documentText); - } else { - documentText = entity.spec?.profile?.displayName || documentText; - } - } - return documentText; - } - private async *execute(): AsyncGenerator { const { token } = await this.tokenManager.getToken(); let entitiesRetrieved = 0; @@ -150,7 +129,7 @@ export class DefaultCatalogCollatorFactory implements DocumentCollatorFactory { kind: entity.kind, name: entity.metadata.name, }), - text: this.getDocumentText(entity), + text: getDocumentText(entity), componentType: entity.spec?.type?.toString() || 'other', type: entity.spec?.type?.toString() || 'other', namespace: entity.metadata.namespace || 'default', diff --git a/plugins/catalog-backend/src/search/util.test.ts b/plugins/catalog-backend/src/search/util.test.ts new file mode 100644 index 0000000000..0444dc2209 --- /dev/null +++ b/plugins/catalog-backend/src/search/util.test.ts @@ -0,0 +1,95 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ComponentEntity, UserEntity } from '@backstage/catalog-model'; +import { getDocumentText } from './util'; + +describe('getDocumentText', () => { + describe('kind is not User or Group', () => { + test('contains description if set', () => { + const entity = createComponent(); + entity.metadata.description = 'The expected description'; + const actual = getDocumentText(entity); + expect(actual).toContain(entity.metadata.description); + }); + + test('is empty if description is not set', () => { + const entity = createComponent(); + const actual = getDocumentText(entity); + expect(actual).toEqual(''); + }); + }); + + describe('kind is User', () => { + test('contains display name if set', () => { + const entity = createUser(); + const actual = getDocumentText(entity); + expect(actual).toContain(entity.spec.profile?.displayName); + }); + + test('contains description if set', () => { + const entity = createUser(); + const actual = getDocumentText(entity); + expect(actual).toContain(entity.metadata.description); + }); + + test('contains both description and display name if both are set', () => { + const entity = createUser(); + const actual = getDocumentText(entity); + expect(actual).toContain(entity.spec.profile?.displayName); + expect(actual).toContain(entity.metadata.description); + }); + + test('is empty if description and display name are not set', () => { + const entity = createUser(); + delete entity.metadata.description; + delete entity.spec.profile?.displayName; + const actual = getDocumentText(entity); + expect(actual).toEqual(''); + }); + }); +}); + +function createUser(): UserEntity { + return { + apiVersion: 'backstage.io/v1alpha1', + kind: 'User', + metadata: { + name: 'user-1', + description: 'The expected description', + }, + spec: { + profile: { + displayName: 'User 1', + }, + }, + }; +} + +function createComponent(): ComponentEntity { + return { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + name: 'component-1', + }, + spec: { + lifecycle: 'experimental', + owner: 'someone', + type: 'service', + }, + }; +} diff --git a/plugins/catalog-backend/src/search/util.ts b/plugins/catalog-backend/src/search/util.ts new file mode 100644 index 0000000000..4e6bb8aea0 --- /dev/null +++ b/plugins/catalog-backend/src/search/util.ts @@ -0,0 +1,35 @@ +/* + * 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 { Entity, UserEntity } from '@backstage/catalog-model'; + +function isUserEntity(entity: Entity): entity is UserEntity { + return entity.kind.toLocaleUpperCase('en-US') === 'USER'; +} + +export function getDocumentText(entity: Entity): string { + let documentText = entity.metadata.description || ''; + if (isUserEntity(entity)) { + if (entity.spec?.profile?.displayName && documentText) { + // combine displayName and description + const displayName = entity.spec.profile.displayName; + documentText = displayName.concat(' : ', documentText); + } else { + documentText = entity.spec?.profile?.displayName || documentText; + } + } + return documentText; +} From 22394f6e42d358ae90303c11c181852cc680e598 Mon Sep 17 00:00:00 2001 From: Bret Hubbard Date: Wed, 30 Mar 2022 10:30:11 -0600 Subject: [PATCH 02/58] catalog-backend: include group displayName in search index Co-authored-by: Jason Nguyen Signed-off-by: Bret Hubbard --- .../catalog-backend/src/search/util.test.ts | 53 ++++++++++++++++++- plugins/catalog-backend/src/search/util.ts | 6 ++- 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/plugins/catalog-backend/src/search/util.test.ts b/plugins/catalog-backend/src/search/util.test.ts index 0444dc2209..d2d1776338 100644 --- a/plugins/catalog-backend/src/search/util.test.ts +++ b/plugins/catalog-backend/src/search/util.test.ts @@ -14,7 +14,11 @@ * limitations under the License. */ -import { ComponentEntity, UserEntity } from '@backstage/catalog-model'; +import { + ComponentEntity, + GroupEntity, + UserEntity, +} from '@backstage/catalog-model'; import { getDocumentText } from './util'; describe('getDocumentText', () => { @@ -61,8 +65,55 @@ describe('getDocumentText', () => { expect(actual).toEqual(''); }); }); + + describe('kind is Group', () => { + test('contains display name if set', () => { + const entity = createGroup(); + const actual = getDocumentText(entity); + expect(actual).toContain(entity.spec.profile?.displayName); + }); + + test('contains description if set', () => { + const entity = createGroup(); + const actual = getDocumentText(entity); + expect(actual).toContain(entity.metadata.description); + }); + + test('contains both description and display name if both are set', () => { + const entity = createGroup(); + const actual = getDocumentText(entity); + expect(actual).toContain(entity.spec.profile?.displayName); + expect(actual).toContain(entity.metadata.description); + }); + + test('is empty if description and display name are not set', () => { + const entity = createGroup(); + delete entity.metadata.description; + delete entity.spec.profile?.displayName; + const actual = getDocumentText(entity); + expect(actual).toEqual(''); + }); + }); }); +function createGroup(): GroupEntity { + return { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Group', + metadata: { + name: 'group-1', + description: 'The expected description', + }, + spec: { + type: 'team', + profile: { + displayName: 'Group 1', + }, + children: [], + }, + }; +} + function createUser(): UserEntity { return { apiVersion: 'backstage.io/v1alpha1', diff --git a/plugins/catalog-backend/src/search/util.ts b/plugins/catalog-backend/src/search/util.ts index 4e6bb8aea0..47a5570899 100644 --- a/plugins/catalog-backend/src/search/util.ts +++ b/plugins/catalog-backend/src/search/util.ts @@ -20,9 +20,13 @@ function isUserEntity(entity: Entity): entity is UserEntity { return entity.kind.toLocaleUpperCase('en-US') === 'USER'; } +function isGroupEntity(entity: Entity): entity is UserEntity { + return entity.kind.toLocaleUpperCase('en-US') === 'GROUP'; +} + export function getDocumentText(entity: Entity): string { let documentText = entity.metadata.description || ''; - if (isUserEntity(entity)) { + if (isUserEntity(entity) || isGroupEntity(entity)) { if (entity.spec?.profile?.displayName && documentText) { // combine displayName and description const displayName = entity.spec.profile.displayName; From 48405ed232722d041b6123b066f6992eacdfaef9 Mon Sep 17 00:00:00 2001 From: Bret Hubbard Date: Wed, 30 Mar 2022 10:37:45 -0600 Subject: [PATCH 03/58] add changeset Signed-off-by: Bret Hubbard --- .changeset/many-cameras-search.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/many-cameras-search.md diff --git a/.changeset/many-cameras-search.md b/.changeset/many-cameras-search.md new file mode 100644 index 0000000000..6998dfd713 --- /dev/null +++ b/.changeset/many-cameras-search.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': patch +--- + +Added `spec.profile.displayName` to search index for Group kinds From 567b13a84aaaa65c7017df1f87c61ff08a67fd12 Mon Sep 17 00:00:00 2001 From: Rogerio Angeliski Date: Thu, 7 Apr 2022 18:06:21 -0300 Subject: [PATCH 04/58] Add checksId option to EntityTechInsightsScorecardContent component Signed-off-by: Rogerio Angeliski --- .changeset/wild-emus-film.md | 5 +++++ plugins/tech-insights/api-report.md | 4 +++- plugins/tech-insights/src/api/TechInsightsApi.ts | 2 +- plugins/tech-insights/src/api/TechInsightsClient.ts | 5 ++--- .../src/components/ScorecardsOverview/ScorecardsOverview.tsx | 4 +++- 5 files changed, 14 insertions(+), 6 deletions(-) create mode 100644 .changeset/wild-emus-film.md diff --git a/.changeset/wild-emus-film.md b/.changeset/wild-emus-film.md new file mode 100644 index 0000000000..abb77c5ddc --- /dev/null +++ b/.changeset/wild-emus-film.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-tech-insights': minor +--- + +Add checksId option to EntityTechInsightsScorecardContent component diff --git a/plugins/tech-insights/api-report.md b/plugins/tech-insights/api-report.md index deadd06010..9574efca28 100644 --- a/plugins/tech-insights/api-report.md +++ b/plugins/tech-insights/api-report.md @@ -34,9 +34,11 @@ export type CheckResultRenderer = { export const EntityTechInsightsScorecardContent: ({ title, description, + checksId, }: { title?: string | undefined; description?: string | undefined; + checksId?: string[] | undefined; }) => JSX.Element; // @public @@ -58,7 +60,7 @@ export interface TechInsightsApi { // (undocumented) runChecks( entityParams: CompoundEntityRef, - checks?: Check[], + checks?: string[], ): Promise; } diff --git a/plugins/tech-insights/src/api/TechInsightsApi.ts b/plugins/tech-insights/src/api/TechInsightsApi.ts index 0a6bb937a6..a24bf74a01 100644 --- a/plugins/tech-insights/src/api/TechInsightsApi.ts +++ b/plugins/tech-insights/src/api/TechInsightsApi.ts @@ -47,7 +47,7 @@ export interface TechInsightsApi { getAllChecks(): Promise; runChecks( entityParams: CompoundEntityRef, - checks?: Check[], + checks?: string[], ): Promise; runBulkChecks( entities: CompoundEntityRef[], diff --git a/plugins/tech-insights/src/api/TechInsightsClient.ts b/plugins/tech-insights/src/api/TechInsightsClient.ts index 5b9af9557f..04de46dba9 100644 --- a/plugins/tech-insights/src/api/TechInsightsClient.ts +++ b/plugins/tech-insights/src/api/TechInsightsClient.ts @@ -75,13 +75,12 @@ export class TechInsightsClient implements TechInsightsApi { async runChecks( entityParams: CompoundEntityRef, - checks?: Check[], + checks?: string[], ): Promise { const url = await this.discoveryApi.getBaseUrl('tech-insights'); const { token } = await this.identityApi.getCredentials(); const { namespace, kind, name } = entityParams; - const checkIds = checks ? checks.map(check => check.id) : []; - const requestBody = { checks: checkIds.length > 0 ? checkIds : undefined }; + const requestBody = { checks }; const response = await fetch( `${url}/checks/run/${encodeURIComponent(namespace)}/${encodeURIComponent( kind, diff --git a/plugins/tech-insights/src/components/ScorecardsOverview/ScorecardsOverview.tsx b/plugins/tech-insights/src/components/ScorecardsOverview/ScorecardsOverview.tsx index 73143a7ea8..53cf826e78 100644 --- a/plugins/tech-insights/src/components/ScorecardsOverview/ScorecardsOverview.tsx +++ b/plugins/tech-insights/src/components/ScorecardsOverview/ScorecardsOverview.tsx @@ -26,14 +26,16 @@ import { techInsightsApiRef } from '../../api/TechInsightsApi'; export const ScorecardsOverview = ({ title, description, + checksId, }: { title?: string; description?: string; + checksId?: string[]; }) => { const api = useApi(techInsightsApiRef); const { namespace, kind, name } = useParams(); const { value, loading, error } = useAsync( - async () => await api.runChecks({ namespace, kind, name }), + async () => await api.runChecks({ namespace, kind, name }, checksId), ); if (loading) { From 3d4542766619d52a1fbf6feb6e4e92d07f336873 Mon Sep 17 00:00:00 2001 From: Luna Stadler Date: Thu, 24 Mar 2022 15:37:33 +0100 Subject: [PATCH 05/58] Make Kubernetes clusters refreshable To make it possible to refresh Kubernetes clusters responsible all places that used ClusterDetails[] before now use the KubernetesClustersSupplier directly and call getClusters() on it. This allows people to use implement custom KubernetesClustersSuppliers that fetch the clusters from somewhere and refresh them using whatever mechanism they might need. Signed-off-by: Luna Stadler --- .changeset/hot-items-smoke.md | 63 +++++++++++++++++++ docs/features/kubernetes/configuration.md | 6 ++ docs/features/kubernetes/installation.md | 59 +++++++++++++++++ plugins/kubernetes-backend/api-report.md | 9 ++- .../MultiTenantServiceLocator.test.ts | 48 ++++++++------ .../MultiTenantServiceLocator.ts | 14 +++-- .../src/service/KubernetesBuilder.ts | 24 +++---- 7 files changed, 179 insertions(+), 44 deletions(-) create mode 100644 .changeset/hot-items-smoke.md diff --git a/.changeset/hot-items-smoke.md b/.changeset/hot-items-smoke.md new file mode 100644 index 0000000000..832604cd35 --- /dev/null +++ b/.changeset/hot-items-smoke.md @@ -0,0 +1,63 @@ +--- +'@backstage/plugin-kubernetes-backend': minor +--- + +**BREAKING** Custom cluster suppliers need to cache their getClusters result + +To allow custom `KubernetesClustersSupplier` instances to refresh the list of clusters +the `getClusters` method is now called whenever the list of clusters is needed. + +Existing `KubernetesClustersSupplier` implementations will need to ensure that `getClusters` +can be called frequently and should return a cached result from `getClusters` instead. + +For example, here's a simple example of this in `packages/backend/src/plugins/kubernetes.ts`: + +```diff +-import { KubernetesBuilder } from '@backstage/plugin-kubernetes-backend'; ++import { ++ ClusterDetails, ++ KubernetesBuilder, ++ KubernetesClustersSupplier, ++} from '@backstage/plugin-kubernetes-backend'; + import { Router } from 'express'; + import { PluginEnvironment } from '../types'; ++import { Duration } from 'luxon'; ++ ++export class CustomClustersSupplier implements KubernetesClustersSupplier { ++ private clusterDetails: ClusterDetails[] = []; ++ ++ async retrieveClusters() { ++ this.clusterDetails = []; // fetch from somewhere ++ } ++ ++ async getClusters(): Promise { ++ return this.clusterDetails; ++ } ++} + + export default async function createPlugin( + env: PluginEnvironment, + ): Promise { +- const { router } = await KubernetesBuilder.createBuilder({ ++ const builder = await KubernetesBuilder.createBuilder({ + logger: env.logger, + config: env.config, +- }).build(); ++ }); ++ ++ const clusterSupplier = new CustomClustersSupplier(); ++ env.scheduler ++ .createScheduledTaskRunner({ ++ frequency: Duration.fromObject({ minutes: 60 }), ++ timeout: Duration.fromObject({ minutes: 15 }), ++ }) ++ .run({ ++ id: 'refresh-kubernetes-clusters', ++ fn: clusterSupplier.retrieveClusters, ++ }); ++ builder.setClusterSupplier(clusterSupplier); ++ ++ const { router } = await builder.build(); + return router; + } +``` diff --git a/docs/features/kubernetes/configuration.md b/docs/features/kubernetes/configuration.md index 612f4903d9..d082d46df2 100644 --- a/docs/features/kubernetes/configuration.md +++ b/docs/features/kubernetes/configuration.md @@ -261,6 +261,12 @@ Kubernetes plugin. Defaults to `false`. +#### Custom `KubernetesClustersSupplier` + +If the configuration-based cluster locators do not work for your use-case, +it is also possible to implement a +[custom `KubernetesClustersSupplier`](installation.md#custom-cluster-discovery). + ### `customResources` (optional) Configures which [custom resources][3] to look for when returning an entity's diff --git a/docs/features/kubernetes/installation.md b/docs/features/kubernetes/installation.md index 2698580491..125889b858 100644 --- a/docs/features/kubernetes/installation.md +++ b/docs/features/kubernetes/installation.md @@ -90,6 +90,65 @@ async function main() { That's it! The Kubernetes frontend and backend have now been added to your Backstage app. +### Custom cluster discovery + +If either existing +[cluster locators](https://backstage.io/docs/features/kubernetes/configuration#clusterlocatormethods) +don't work for your use-case, it is possible to implement a custom +[KubernetesClustersSupplier](https://backstage.io/docs/reference/plugin-kubernetes-backend.kubernetesclusterssupplier). + +Change the following in `packages/backend/src/plugin/kubernetes.ts`: + +```diff +-import { KubernetesBuilder } from '@backstage/plugin-kubernetes-backend'; ++import { ++ ClusterDetails, ++ KubernetesBuilder, ++ KubernetesClustersSupplier, ++} from '@backstage/plugin-kubernetes-backend'; + import { Router } from 'express'; + import { PluginEnvironment } from '../types'; ++import { Duration } from 'luxon'; ++ ++export class CustomClustersSupplier implements KubernetesClustersSupplier { ++ private clusterDetails: ClusterDetails[] = []; ++ ++ async retrieveClusters() { ++ this.clusterDetails = []; // fetch from somewhere ++ } ++ ++ async getClusters(): Promise { ++ return this.clusterDetails; ++ } ++} + + export default async function createPlugin( + env: PluginEnvironment, + ): Promise { +- const { router } = await KubernetesBuilder.createBuilder({ ++ const builder = await KubernetesBuilder.createBuilder({ + logger: env.logger, + config: env.config, +- }).build(); ++ }); ++ ++ const clusterSupplier = new CustomClustersSupplier(); ++ env.scheduler ++ .createScheduledTaskRunner({ ++ frequency: Duration.fromObject({ minutes: 60 }), ++ timeout: Duration.fromObject({ minutes: 15 }), ++ }) ++ .run({ ++ id: 'refresh-kubernetes-clusters', ++ fn: clusterSupplier.retrieveClusters, ++ }); ++ builder.setClusterSupplier(clusterSupplier); ++ ++ const { router } = await builder.build(); + return router; + } +``` + ## Running Backstage locally Start the frontend and the backend app by diff --git a/plugins/kubernetes-backend/api-report.md b/plugins/kubernetes-backend/api-report.md index 8a3b64bd93..c00f68a13f 100644 --- a/plugins/kubernetes-backend/api-report.md +++ b/plugins/kubernetes-backend/api-report.md @@ -92,11 +92,11 @@ export class KubernetesBuilder { protected buildFetcher(): KubernetesFetcher; // (undocumented) protected buildHttpServiceLocator( - _clusterDetails: ClusterDetails[], + _clusterSupplier: KubernetesClustersSupplier, ): KubernetesServiceLocator; // (undocumented) protected buildMultiTenantServiceLocator( - clusterDetails: ClusterDetails[], + clusterSupplier: KubernetesClustersSupplier, ): KubernetesServiceLocator; // (undocumented) protected buildObjectsProvider( @@ -105,12 +105,12 @@ export class KubernetesBuilder { // (undocumented) protected buildRouter( objectsProvider: KubernetesObjectsProvider, - clusterDetails: ClusterDetails[], + clusterSupplier: KubernetesClustersSupplier, ): express.Router; // (undocumented) protected buildServiceLocator( method: ServiceLocatorMethod, - clusterDetails: ClusterDetails[], + clusterSupplier: KubernetesClustersSupplier, ): KubernetesServiceLocator; // (undocumented) static createBuilder(env: KubernetesEnvironment): KubernetesBuilder; @@ -137,7 +137,6 @@ export class KubernetesBuilder { // @public export type KubernetesBuilderReturn = Promise<{ router: express.Router; - clusterDetails: ClusterDetails[]; clusterSupplier: KubernetesClustersSupplier; customResources: CustomResource[]; fetcher: KubernetesFetcher; diff --git a/plugins/kubernetes-backend/src/service-locator/MultiTenantServiceLocator.test.ts b/plugins/kubernetes-backend/src/service-locator/MultiTenantServiceLocator.test.ts index 8586c5e445..f97161591f 100644 --- a/plugins/kubernetes-backend/src/service-locator/MultiTenantServiceLocator.test.ts +++ b/plugins/kubernetes-backend/src/service-locator/MultiTenantServiceLocator.test.ts @@ -19,7 +19,7 @@ import { MultiTenantServiceLocator } from './MultiTenantServiceLocator'; describe('MultiTenantConfigClusterLocator', () => { it('empty clusters returns empty cluster details', async () => { - const sut = new MultiTenantServiceLocator([]); + const sut = new MultiTenantServiceLocator({ getClusters: async () => [] }); const result = await sut.getClustersByServiceId('ignored'); @@ -27,14 +27,18 @@ describe('MultiTenantConfigClusterLocator', () => { }); it('one clusters returns one cluster details', async () => { - const sut = new MultiTenantServiceLocator([ - { - name: 'cluster1', - url: 'http://localhost:8080', - authProvider: 'serviceAccount', - serviceAccountToken: '12345', + const sut = new MultiTenantServiceLocator({ + getClusters: async () => { + return [ + { + name: 'cluster1', + url: 'http://localhost:8080', + authProvider: 'serviceAccount', + serviceAccountToken: '12345', + }, + ]; }, - ]); + }); const result = await sut.getClustersByServiceId('ignored'); @@ -49,19 +53,23 @@ describe('MultiTenantConfigClusterLocator', () => { }); it('two clusters returns two cluster details', async () => { - const sut = new MultiTenantServiceLocator([ - { - name: 'cluster1', - serviceAccountToken: 'token', - url: 'http://localhost:8080', - authProvider: 'serviceAccount', + const sut = new MultiTenantServiceLocator({ + getClusters: async () => { + return [ + { + name: 'cluster1', + serviceAccountToken: 'token', + url: 'http://localhost:8080', + authProvider: 'serviceAccount', + }, + { + name: 'cluster2', + url: 'http://localhost:8081', + authProvider: 'google', + }, + ]; }, - { - name: 'cluster2', - url: 'http://localhost:8081', - authProvider: 'google', - }, - ]); + }); const result = await sut.getClustersByServiceId('ignored'); diff --git a/plugins/kubernetes-backend/src/service-locator/MultiTenantServiceLocator.ts b/plugins/kubernetes-backend/src/service-locator/MultiTenantServiceLocator.ts index 9f874c7fc8..30c66a38d1 100644 --- a/plugins/kubernetes-backend/src/service-locator/MultiTenantServiceLocator.ts +++ b/plugins/kubernetes-backend/src/service-locator/MultiTenantServiceLocator.ts @@ -14,20 +14,24 @@ * limitations under the License. */ -import { ClusterDetails, KubernetesServiceLocator } from '../types/types'; +import { + ClusterDetails, + KubernetesClustersSupplier, + KubernetesServiceLocator, +} from '../types/types'; // This locator assumes that every service is located on every cluster // Therefore it will always return all clusters provided export class MultiTenantServiceLocator implements KubernetesServiceLocator { - private readonly clusterDetails: ClusterDetails[]; + private readonly clusterSupplier: KubernetesClustersSupplier; - constructor(clusterDetails: ClusterDetails[]) { - this.clusterDetails = clusterDetails; + constructor(clusterSupplier: KubernetesClustersSupplier) { + this.clusterSupplier = clusterSupplier; } // As this implementation always returns all clusters serviceId is ignored here // eslint-disable-next-line @typescript-eslint/no-unused-vars async getClustersByServiceId(_serviceId: string): Promise { - return this.clusterDetails; + return this.clusterSupplier.getClusters(); } } diff --git a/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts b/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts index a1eb60a239..6f5cfd0add 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts @@ -20,7 +20,6 @@ import { Logger } from 'winston'; import { getCombinedClusterDetails } from '../cluster-locator'; import { MultiTenantServiceLocator } from '../service-locator/MultiTenantServiceLocator'; import { - ClusterDetails, KubernetesObjectTypes, ServiceLocatorMethod, CustomResource, @@ -50,7 +49,6 @@ export interface KubernetesEnvironment { */ export type KubernetesBuilderReturn = Promise<{ router: express.Router; - clusterDetails: ClusterDetails[]; clusterSupplier: KubernetesClustersSupplier; customResources: CustomResource[]; fetcher: KubernetesFetcher; @@ -93,11 +91,9 @@ export class KubernetesBuilder { const clusterSupplier = this.clusterSupplier ?? this.buildClusterSupplier(); - const clusterDetails = await this.fetchClusterDetails(clusterSupplier); - const serviceLocator = this.serviceLocator ?? - this.buildServiceLocator(this.getServiceLocatorMethod(), clusterDetails); + this.buildServiceLocator(this.getServiceLocatorMethod(), clusterSupplier); const objectsProvider = this.objectsProvider ?? @@ -109,10 +105,9 @@ export class KubernetesBuilder { objectTypesToFetch: this.getObjectTypesToFetch(), }); - const router = this.buildRouter(objectsProvider, clusterDetails); + const router = this.buildRouter(objectsProvider, clusterSupplier); return { - clusterDetails, clusterSupplier, customResources, fetcher, @@ -185,13 +180,13 @@ export class KubernetesBuilder { protected buildServiceLocator( method: ServiceLocatorMethod, - clusterDetails: ClusterDetails[], + clusterSupplier: KubernetesClustersSupplier, ): KubernetesServiceLocator { switch (method) { case 'multiTenant': - return this.buildMultiTenantServiceLocator(clusterDetails); + return this.buildMultiTenantServiceLocator(clusterSupplier); case 'http': - return this.buildHttpServiceLocator(clusterDetails); + return this.buildHttpServiceLocator(clusterSupplier); default: throw new Error( `Unsupported kubernetes.clusterLocatorMethod "${method}"`, @@ -200,20 +195,20 @@ export class KubernetesBuilder { } protected buildMultiTenantServiceLocator( - clusterDetails: ClusterDetails[], + clusterSupplier: KubernetesClustersSupplier, ): KubernetesServiceLocator { - return new MultiTenantServiceLocator(clusterDetails); + return new MultiTenantServiceLocator(clusterSupplier); } protected buildHttpServiceLocator( - _clusterDetails: ClusterDetails[], + _clusterSupplier: KubernetesClustersSupplier, ): KubernetesServiceLocator { throw new Error('not implemented'); } protected buildRouter( objectsProvider: KubernetesObjectsProvider, - clusterDetails: ClusterDetails[], + clusterSupplier: KubernetesClustersSupplier, ): express.Router { const logger = this.env.logger; const router = Router(); @@ -236,6 +231,7 @@ export class KubernetesBuilder { }); router.get('/clusters', async (_, res) => { + const clusterDetails = await this.fetchClusterDetails(clusterSupplier); res.json({ items: clusterDetails.map(cd => ({ name: cd.name, From 5818bead7d20bb59b3989ca3f9b1348e9e3fd570 Mon Sep 17 00:00:00 2001 From: Luna Stadler Date: Tue, 29 Mar 2022 11:22:22 +0200 Subject: [PATCH 06/58] Ensure GkeClusterLocator only fetches the clusters once This is now necessary because cluster suppliers are called whenever the list of clusters is required and thus should cache their clusters. Signed-off-by: Luna Stadler --- .../src/cluster-locator/GkeClusterLocator.ts | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.ts b/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.ts index 8b70db40eb..989b69c7c8 100644 --- a/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.ts +++ b/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.ts @@ -17,7 +17,11 @@ import { Config } from '@backstage/config'; import { ForwardedError } from '@backstage/errors'; import * as container from '@google-cloud/container'; -import { GKEClusterDetails, KubernetesClustersSupplier } from '../types/types'; +import { + ClusterDetails, + GKEClusterDetails, + KubernetesClustersSupplier, +} from '../types/types'; type GkeClusterLocatorOptions = { projectId: string; @@ -31,6 +35,7 @@ export class GkeClusterLocator implements KubernetesClustersSupplier { constructor( private readonly options: GkeClusterLocatorOptions, private readonly client: container.v1.ClusterManagerClient, + private clusterDetails: GKEClusterDetails[] | undefined = undefined, ) {} static fromConfigWithClient( @@ -55,8 +60,17 @@ export class GkeClusterLocator implements KubernetesClustersSupplier { ); } + async getClusters(): Promise { + if (this.clusterDetails) { + return this.clusterDetails; + } + + this.clusterDetails = await this.retrieveClusters(); + return this.clusterDetails; + } + // TODO pass caData into the object - async getClusters(): Promise { + async retrieveClusters(): Promise { const { projectId, region, From 38ea1f136c7f61ec5fcad1adbca45b1ac237a240 Mon Sep 17 00:00:00 2001 From: Luna Stadler Date: Tue, 29 Mar 2022 12:03:21 +0200 Subject: [PATCH 07/58] List existing cluster locator methods in one place I found the nested headings difficult to read, so this now lists all available methods in one place. Signed-off-by: Luna Stadler --- docs/features/kubernetes/configuration.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/features/kubernetes/configuration.md b/docs/features/kubernetes/configuration.md index d082d46df2..dd7e666be4 100644 --- a/docs/features/kubernetes/configuration.md +++ b/docs/features/kubernetes/configuration.md @@ -57,6 +57,10 @@ This is an array used to determine where to retrieve cluster configuration from. Valid cluster locator methods are: +- [`config`](#config) +- [`gke`](#gke) +- [custom `KubernetesClustersSupplier`](#custom-kubernetesclusterssupplier) + #### `config` This cluster locator method will read cluster information from your app-config From 8d050f714d4e73662772f82b50cce176c2c8cbfb Mon Sep 17 00:00:00 2001 From: Luna Stadler Date: Mon, 4 Apr 2022 14:26:11 +0200 Subject: [PATCH 08/58] Make Kubernetes cluster refresh more explicit The `refreshClusters` method is now part of the `KubernetesClustersSupplier` interface definition and also documented. All existing cluster suppliers now implement it as well and the examples in the docs and in the CHANGELOG have been adjusted. Signed-off-by: Luna Stadler --- .changeset/hot-items-smoke.md | 19 ++--- docs/features/kubernetes/installation.md | 19 ++--- plugins/kubernetes-backend/api-report.md | 4 +- .../cluster-locator/ConfigClusterLocator.ts | 2 + .../cluster-locator/GkeClusterLocator.test.ts | 7 +- .../src/cluster-locator/GkeClusterLocator.ts | 11 +-- .../src/cluster-locator/index.test.ts | 10 +-- .../src/cluster-locator/index.ts | 71 +++++++++++-------- .../MultiTenantServiceLocator.test.ts | 7 +- .../src/service/KubernetesBuilder.test.ts | 2 + .../src/service/KubernetesBuilder.ts | 25 +++++-- .../src/service/runPeriodically.ts | 54 ++++++++++++++ plugins/kubernetes-backend/src/types/types.ts | 11 +++ 13 files changed, 166 insertions(+), 76 deletions(-) create mode 100644 plugins/kubernetes-backend/src/service/runPeriodically.ts diff --git a/.changeset/hot-items-smoke.md b/.changeset/hot-items-smoke.md index 832604cd35..52c5088d3e 100644 --- a/.changeset/hot-items-smoke.md +++ b/.changeset/hot-items-smoke.md @@ -21,12 +21,11 @@ For example, here's a simple example of this in `packages/backend/src/plugins/ku +} from '@backstage/plugin-kubernetes-backend'; import { Router } from 'express'; import { PluginEnvironment } from '../types'; -+import { Duration } from 'luxon'; -+ + +export class CustomClustersSupplier implements KubernetesClustersSupplier { + private clusterDetails: ClusterDetails[] = []; + -+ async retrieveClusters() { ++ async refreshClusters(): Promise { + this.clusterDetails = []; // fetch from somewhere + } + @@ -34,7 +33,7 @@ For example, here's a simple example of this in `packages/backend/src/plugins/ku + return this.clusterDetails; + } +} - ++ export default async function createPlugin( env: PluginEnvironment, ): Promise { @@ -46,18 +45,12 @@ For example, here's a simple example of this in `packages/backend/src/plugins/ku + }); + + const clusterSupplier = new CustomClustersSupplier(); -+ env.scheduler -+ .createScheduledTaskRunner({ -+ frequency: Duration.fromObject({ minutes: 60 }), -+ timeout: Duration.fromObject({ minutes: 15 }), -+ }) -+ .run({ -+ id: 'refresh-kubernetes-clusters', -+ fn: clusterSupplier.retrieveClusters, -+ }); + builder.setClusterSupplier(clusterSupplier); + + const { router } = await builder.build(); return router; } ``` + +If you need to adjust the refresh interval from the default once per hour +you can call `builder.setClusterRefreshInterval`. diff --git a/docs/features/kubernetes/installation.md b/docs/features/kubernetes/installation.md index 125889b858..4b4ba1139d 100644 --- a/docs/features/kubernetes/installation.md +++ b/docs/features/kubernetes/installation.md @@ -108,12 +108,11 @@ Change the following in `packages/backend/src/plugin/kubernetes.ts`: +} from '@backstage/plugin-kubernetes-backend'; import { Router } from 'express'; import { PluginEnvironment } from '../types'; -+import { Duration } from 'luxon'; -+ + +export class CustomClustersSupplier implements KubernetesClustersSupplier { + private clusterDetails: ClusterDetails[] = []; + -+ async retrieveClusters() { ++ async refreshClusters(): Promise { + this.clusterDetails = []; // fetch from somewhere + } + @@ -121,7 +120,7 @@ Change the following in `packages/backend/src/plugin/kubernetes.ts`: + return this.clusterDetails; + } +} - ++ export default async function createPlugin( env: PluginEnvironment, ): Promise { @@ -133,15 +132,6 @@ Change the following in `packages/backend/src/plugin/kubernetes.ts`: + }); + + const clusterSupplier = new CustomClustersSupplier(); -+ env.scheduler -+ .createScheduledTaskRunner({ -+ frequency: Duration.fromObject({ minutes: 60 }), -+ timeout: Duration.fromObject({ minutes: 15 }), -+ }) -+ .run({ -+ id: 'refresh-kubernetes-clusters', -+ fn: clusterSupplier.retrieveClusters, -+ }); + builder.setClusterSupplier(clusterSupplier); + + const { router } = await builder.build(); @@ -149,6 +139,9 @@ Change the following in `packages/backend/src/plugin/kubernetes.ts`: } ``` +If you need to adjust the refresh interval from the default once per hour +you can call `builder.setClusterRefreshInterval`. + ## Running Backstage locally Start the frontend and the backend app by diff --git a/plugins/kubernetes-backend/api-report.md b/plugins/kubernetes-backend/api-report.md index c00f68a13f..573198acf0 100644 --- a/plugins/kubernetes-backend/api-report.md +++ b/plugins/kubernetes-backend/api-report.md @@ -125,6 +125,8 @@ export class KubernetesBuilder { // (undocumented) protected getServiceLocatorMethod(): ServiceLocatorMethod; // (undocumented) + setClusterRefreshInterval(refreshMs: number): this; + // (undocumented) setClusterSupplier(clusterSupplier?: KubernetesClustersSupplier): this; // (undocumented) setFetcher(fetcher?: KubernetesFetcher): this; @@ -148,8 +150,8 @@ export type KubernetesBuilderReturn = Promise<{ // // @public (undocumented) export interface KubernetesClustersSupplier { - // (undocumented) getClusters(): Promise; + refreshClusters(): Promise; } // Warning: (ae-missing-release-tag) "KubernetesEnvironment" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) diff --git a/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.ts b/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.ts index 1bde1226dd..893db0f5d0 100644 --- a/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.ts +++ b/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.ts @@ -77,6 +77,8 @@ export class ConfigClusterLocator implements KubernetesClustersSupplier { ); } + async refreshClusters(): Promise {} + async getClusters(): Promise { return this.clusterDetails; } diff --git a/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.test.ts b/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.test.ts index 6bef8e0009..51062066da 100644 --- a/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.test.ts +++ b/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.test.ts @@ -69,6 +69,7 @@ describe('GkeClusterLocator', () => { listClusters: mockedListClusters, } as any); + await sut.refreshClusters(); const result = await sut.getClusters(); expect(result).toStrictEqual([]); @@ -100,6 +101,7 @@ describe('GkeClusterLocator', () => { listClusters: mockedListClusters, } as any); + await sut.refreshClusters(); const result = await sut.getClusters(); expect(result).toStrictEqual([ @@ -137,6 +139,7 @@ describe('GkeClusterLocator', () => { listClusters: mockedListClusters, } as any); + await sut.refreshClusters(); const result = await sut.getClusters(); expect(result).toStrictEqual([ @@ -179,6 +182,7 @@ describe('GkeClusterLocator', () => { listClusters: mockedListClusters, } as any); + await sut.refreshClusters(); const result = await sut.getClusters(); expect(result).toStrictEqual([ @@ -217,7 +221,7 @@ describe('GkeClusterLocator', () => { listClusters: mockedListClusters, } as any); - await expect(sut.getClusters()).rejects.toThrow( + await expect(sut.refreshClusters()).rejects.toThrow( 'There was an error retrieving clusters from GKE for projectId=some-project region=some-region; caused by Error: some error', ); @@ -250,6 +254,7 @@ describe('GkeClusterLocator', () => { listClusters: mockedListClusters, } as any); + await sut.refreshClusters(); const result = await sut.getClusters(); expect(result).toStrictEqual([ diff --git a/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.ts b/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.ts index 989b69c7c8..8484f5006b 100644 --- a/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.ts +++ b/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.ts @@ -61,16 +61,11 @@ export class GkeClusterLocator implements KubernetesClustersSupplier { } async getClusters(): Promise { - if (this.clusterDetails) { - return this.clusterDetails; - } - - this.clusterDetails = await this.retrieveClusters(); - return this.clusterDetails; + return this.clusterDetails ?? []; } // TODO pass caData into the object - async retrieveClusters(): Promise { + async refreshClusters(): Promise { const { projectId, region, @@ -84,7 +79,7 @@ export class GkeClusterLocator implements KubernetesClustersSupplier { try { const [response] = await this.client.listClusters(request); - return (response.clusters ?? []).map(r => ({ + this.clusterDetails = (response.clusters ?? []).map(r => ({ // TODO filter out clusters which don't have name or endpoint name: r.name ?? 'unknown', url: `https://${r.endpoint ?? ''}`, diff --git a/plugins/kubernetes-backend/src/cluster-locator/index.test.ts b/plugins/kubernetes-backend/src/cluster-locator/index.test.ts index 2bc2c719a0..2bdc37c31c 100644 --- a/plugins/kubernetes-backend/src/cluster-locator/index.test.ts +++ b/plugins/kubernetes-backend/src/cluster-locator/index.test.ts @@ -15,9 +15,9 @@ */ import { Config, ConfigReader } from '@backstage/config'; -import { getCombinedClusterDetails } from './index'; +import { getCombinedClusterSupplier } from './index'; -describe('getCombinedClusterDetails', () => { +describe('getCombinedClusterSupplier', () => { it('should retrieve cluster details from config', async () => { const config: Config = new ConfigReader( { @@ -45,7 +45,9 @@ describe('getCombinedClusterDetails', () => { 'ctx', ); - const result = await getCombinedClusterDetails(config); + const clusterSupplier = getCombinedClusterSupplier(config); + await clusterSupplier.refreshClusters(); + const result = await clusterSupplier.getClusters(); expect(result).toStrictEqual([ { @@ -99,7 +101,7 @@ describe('getCombinedClusterDetails', () => { 'ctx', ); - await expect(getCombinedClusterDetails(config)).rejects.toStrictEqual( + expect(() => getCombinedClusterSupplier(config)).toThrowError( new Error('Unsupported kubernetes.clusterLocatorMethods: "magic"'), ); }); diff --git a/plugins/kubernetes-backend/src/cluster-locator/index.ts b/plugins/kubernetes-backend/src/cluster-locator/index.ts index a4bcf77395..fec92d06d7 100644 --- a/plugins/kubernetes-backend/src/cluster-locator/index.ts +++ b/plugins/kubernetes-backend/src/cluster-locator/index.ts @@ -15,38 +15,51 @@ */ import { Config } from '@backstage/config'; -import { ClusterDetails } from '../types/types'; +import { ClusterDetails, KubernetesClustersSupplier } from '../types/types'; import { ConfigClusterLocator } from './ConfigClusterLocator'; import { GkeClusterLocator } from './GkeClusterLocator'; -export const getCombinedClusterDetails = async ( +class CombinedClustersSupplier implements KubernetesClustersSupplier { + constructor( + readonly clusterSuppliers: KubernetesClustersSupplier[], + private clusterDetails: ClusterDetails[] | undefined = undefined, + ) {} + + async refreshClusters(): Promise { + this.clusterDetails = await Promise.all( + this.clusterSuppliers.map(supplier => supplier.getClusters()), + ) + .then(res => { + return res.flat(); + }) + .catch(e => { + throw e; + }); + } + + async getClusters(): Promise { + return this.clusterDetails ?? []; + } +} + +export const getCombinedClusterSupplier = ( rootConfig: Config, -): Promise => { - return Promise.all( - rootConfig - .getConfigArray('kubernetes.clusterLocatorMethods') - .map(clusterLocatorMethod => { - const type = clusterLocatorMethod.getString('type'); - switch (type) { - case 'config': - return ConfigClusterLocator.fromConfig( - clusterLocatorMethod, - ).getClusters(); - case 'gke': - return GkeClusterLocator.fromConfig( - clusterLocatorMethod, - ).getClusters(); - default: - throw new Error( - `Unsupported kubernetes.clusterLocatorMethods: "${type}"`, - ); - } - }), - ) - .then(res => { - return res.flat(); - }) - .catch(e => { - throw e; +): KubernetesClustersSupplier => { + const clusterSuppliers = rootConfig + .getConfigArray('kubernetes.clusterLocatorMethods') + .map(clusterLocatorMethod => { + const type = clusterLocatorMethod.getString('type'); + switch (type) { + case 'config': + return ConfigClusterLocator.fromConfig(clusterLocatorMethod); + case 'gke': + return GkeClusterLocator.fromConfig(clusterLocatorMethod); + default: + throw new Error( + `Unsupported kubernetes.clusterLocatorMethods: "${type}"`, + ); + } }); + + return new CombinedClustersSupplier(clusterSuppliers); }; diff --git a/plugins/kubernetes-backend/src/service-locator/MultiTenantServiceLocator.test.ts b/plugins/kubernetes-backend/src/service-locator/MultiTenantServiceLocator.test.ts index f97161591f..974f554f45 100644 --- a/plugins/kubernetes-backend/src/service-locator/MultiTenantServiceLocator.test.ts +++ b/plugins/kubernetes-backend/src/service-locator/MultiTenantServiceLocator.test.ts @@ -19,7 +19,10 @@ import { MultiTenantServiceLocator } from './MultiTenantServiceLocator'; describe('MultiTenantConfigClusterLocator', () => { it('empty clusters returns empty cluster details', async () => { - const sut = new MultiTenantServiceLocator({ getClusters: async () => [] }); + const sut = new MultiTenantServiceLocator({ + refreshClusters: async () => {}, + getClusters: async () => [], + }); const result = await sut.getClustersByServiceId('ignored'); @@ -28,6 +31,7 @@ describe('MultiTenantConfigClusterLocator', () => { it('one clusters returns one cluster details', async () => { const sut = new MultiTenantServiceLocator({ + refreshClusters: async () => {}, getClusters: async () => { return [ { @@ -54,6 +58,7 @@ describe('MultiTenantConfigClusterLocator', () => { it('two clusters returns two cluster details', async () => { const sut = new MultiTenantServiceLocator({ + refreshClusters: async () => {}, getClusters: async () => { return [ { diff --git a/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts b/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts index 37dad8c3e4..c3afa4fb6a 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts @@ -59,6 +59,7 @@ describe('KubernetesBuilder', () => { }, ]; const clusterSupplier: KubernetesClustersSupplier = { + async refreshClusters() {}, async getClusters() { return clusters; }, @@ -179,6 +180,7 @@ describe('KubernetesBuilder', () => { }, ]; const clusterSupplier: KubernetesClustersSupplier = { + async refreshClusters() {}, async getClusters() { return clusters; }, diff --git a/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts b/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts index 6f5cfd0add..9cdef9f00d 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts @@ -17,7 +17,7 @@ import { Config } from '@backstage/config'; import express from 'express'; import Router from 'express-promise-router'; import { Logger } from 'winston'; -import { getCombinedClusterDetails } from '../cluster-locator'; +import { getCombinedClusterSupplier } from '../cluster-locator'; import { MultiTenantServiceLocator } from '../service-locator/MultiTenantServiceLocator'; import { KubernetesObjectTypes, @@ -36,6 +36,7 @@ import { KubernetesFanOutHandler, } from './KubernetesFanOutHandler'; import { KubernetesClientBasedFetcher } from './KubernetesFetcher'; +import { runPeriodically } from './runPeriodically'; export interface KubernetesEnvironment { logger: Logger; @@ -58,6 +59,7 @@ export type KubernetesBuilderReturn = Promise<{ export class KubernetesBuilder { private clusterSupplier?: KubernetesClustersSupplier; + private clusterRefreshMs: number = 60 * 60 * 1000; // defaults to once per hour private objectsProvider?: KubernetesObjectsProvider; private fetcher?: KubernetesFetcher; private serviceLocator?: KubernetesServiceLocator; @@ -91,6 +93,16 @@ export class KubernetesBuilder { const clusterSupplier = this.clusterSupplier ?? this.buildClusterSupplier(); + // we cannot use the regular scheduler here because all instances need this info + // and it is not persisted anywhere. + runPeriodically(async () => { + try { + await clusterSupplier.refreshClusters(); + } catch (e) { + logger.warn(`Failed to refresh kubernetes clusters: ${e}`); + } + }, this.clusterRefreshMs); + const serviceLocator = this.serviceLocator ?? this.buildServiceLocator(this.getServiceLocatorMethod(), clusterSupplier); @@ -122,6 +134,11 @@ export class KubernetesBuilder { return this; } + public setClusterRefreshInterval(refreshMs: number) { + this.clusterRefreshMs = refreshMs; + return this; + } + public setObjectsProvider(objectsProvider?: KubernetesObjectsProvider) { this.objectsProvider = objectsProvider; return this; @@ -158,11 +175,7 @@ export class KubernetesBuilder { protected buildClusterSupplier(): KubernetesClustersSupplier { const config = this.env.config; - return { - getClusters() { - return getCombinedClusterDetails(config); - }, - }; + return getCombinedClusterSupplier(config); } protected buildObjectsProvider( diff --git a/plugins/kubernetes-backend/src/service/runPeriodically.ts b/plugins/kubernetes-backend/src/service/runPeriodically.ts new file mode 100644 index 0000000000..2f3104e221 --- /dev/null +++ b/plugins/kubernetes-backend/src/service/runPeriodically.ts @@ -0,0 +1,54 @@ +/* + * 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. + */ + +/** + * Runs a function repeatedly, with a fixed wait between invocations. + * + * Supports async functions, and silently ignores exceptions and rejections. + * + * @param fn - The function to run. May return a Promise. + * @param delayMs - The delay between a completed function invocation and the + * next. + * @returns A function that, when called, stops the invocation loop. + */ +export function runPeriodically(fn: () => any, delayMs: number): () => void { + let cancel: () => void; + let cancelled = false; + const cancellationPromise = new Promise(resolve => { + cancel = () => { + resolve(); + cancelled = true; + }; + }); + + const startRefresh = async () => { + while (!cancelled) { + try { + await fn(); + } catch { + // ignore intentionally + } + + await Promise.race([ + new Promise(resolve => setTimeout(resolve, delayMs)), + cancellationPromise, + ]); + } + }; + startRefresh(); + + return cancel!; +} diff --git a/plugins/kubernetes-backend/src/types/types.ts b/plugins/kubernetes-backend/src/types/types.ts index 37c26956fe..512d916639 100644 --- a/plugins/kubernetes-backend/src/types/types.ts +++ b/plugins/kubernetes-backend/src/types/types.ts @@ -80,6 +80,17 @@ export type KubernetesObjectTypes = // Used to load cluster details from different sources export interface KubernetesClustersSupplier { + /** + * Refreshes the list of cluster from the source. + * + * This will be called periodically on a schedule to refresh the list + * of clusters. + */ + refreshClusters(): Promise; + + /** + * Returns the cached list of clusters. + */ getClusters(): Promise; } From 67dbe016713b457aa3def29ac2439d181a99443b Mon Sep 17 00:00:00 2001 From: Jason Nguyen Date: Fri, 8 Apr 2022 09:26:23 -0600 Subject: [PATCH 09/58] catalog-backend: simplify getDocumentText Signed-off-by: Jason Nguyen --- plugins/catalog-backend/src/search/util.ts | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/plugins/catalog-backend/src/search/util.ts b/plugins/catalog-backend/src/search/util.ts index 47a5570899..7e7ce7064e 100644 --- a/plugins/catalog-backend/src/search/util.ts +++ b/plugins/catalog-backend/src/search/util.ts @@ -25,15 +25,13 @@ function isGroupEntity(entity: Entity): entity is UserEntity { } export function getDocumentText(entity: Entity): string { - let documentText = entity.metadata.description || ''; + const documentTexts: string[] = []; + documentTexts.push(entity.metadata.description || ''); + if (isUserEntity(entity) || isGroupEntity(entity)) { - if (entity.spec?.profile?.displayName && documentText) { - // combine displayName and description - const displayName = entity.spec.profile.displayName; - documentText = displayName.concat(' : ', documentText); - } else { - documentText = entity.spec?.profile?.displayName || documentText; + if (entity.spec?.profile?.displayName) { + documentTexts.push(entity.spec.profile.displayName); } } - return documentText; + return documentTexts.join(' : '); } From c0d0e2bccb4fe26b79d220b2ed8d99e3499b3948 Mon Sep 17 00:00:00 2001 From: LvffY Date: Sat, 2 Apr 2022 15:39:17 +0200 Subject: [PATCH 10/58] =?UTF-8?q?[#10582]=20=F0=9F=90=9B=20Use=20getEntity?= =?UTF-8?q?SourceLocation=20instead=20of=20custom=20method=20to=20get=20th?= =?UTF-8?q?e=20entity=20source=20URL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: LvffY (cherry picked from commit f0e86e8ba349cf7056c64960b7ad39740dad4cf6) --- .../src/service/TodoReaderService.ts | 39 +------------------ 1 file changed, 2 insertions(+), 37 deletions(-) diff --git a/plugins/todo-backend/src/service/TodoReaderService.ts b/plugins/todo-backend/src/service/TodoReaderService.ts index 4397f34045..1b3376dbfd 100644 --- a/plugins/todo-backend/src/service/TodoReaderService.ts +++ b/plugins/todo-backend/src/service/TodoReaderService.ts @@ -17,10 +17,7 @@ import { InputError, NotFoundError } from '@backstage/errors'; import { CatalogApi } from '@backstage/catalog-client'; import { - ANNOTATION_LOCATION, - ANNOTATION_SOURCE_LOCATION, - Entity, - parseLocationRef, + getEntitySourceLocation, stringifyEntityRef, } from '@backstage/catalog-model'; import { TodoReader } from '../lib'; @@ -75,7 +72,7 @@ export class TodoReaderService implements TodoService { ); } - const url = this.getEntitySourceUrl(entity); + const url = getEntitySourceLocation(entity).target; const todos = await this.todoReader.readTodos({ url }); let limit = req.limit ?? this.defaultPageSize; @@ -125,36 +122,4 @@ export class TodoReaderService implements TodoService { limit, }; } - - private getEntitySourceUrl(entity: Entity) { - const sourceLocation = - entity.metadata.annotations?.[ANNOTATION_SOURCE_LOCATION]; - if (sourceLocation) { - const parsed = parseLocationRef(sourceLocation); - if (parsed.type !== 'url') { - throw new InputError( - `Invalid entity source location type for ${stringifyEntityRef( - entity, - )}, got '${parsed.type}'`, - ); - } - return parsed.target; - } - - const location = entity.metadata.annotations?.[ANNOTATION_LOCATION]; - if (location) { - const parsed = parseLocationRef(location); - if (parsed.type !== 'url') { - throw new InputError( - `Invalid entity location type for ${stringifyEntityRef( - entity, - )}, got '${parsed.type}'`, - ); - } - return parsed.target; - } - throw new InputError( - `No entity location annotation found for ${stringifyEntityRef(entity)}`, - ); - } } From 1b13978d4d1ee85aaf09d092c3c8a021478244fc Mon Sep 17 00:00:00 2001 From: LvffY Date: Sat, 2 Apr 2022 17:19:33 +0200 Subject: [PATCH 11/58] =?UTF-8?q?[#10582]=20=F0=9F=92=9A=20Fix=20tests=20f?= =?UTF-8?q?or=20todo-backend?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: LvffY (cherry picked from commit eba6328126af2e20a429c96081ae96c4615a7c9d) --- .../src/service/TodoReaderService.test.ts | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/plugins/todo-backend/src/service/TodoReaderService.test.ts b/plugins/todo-backend/src/service/TodoReaderService.test.ts index 943462bd63..f99a9b7502 100644 --- a/plugins/todo-backend/src/service/TodoReaderService.test.ts +++ b/plugins/todo-backend/src/service/TodoReaderService.test.ts @@ -310,7 +310,7 @@ describe('TodoReaderService', () => { }); }); - it('should throw if entity does not have a location', async () => { + it('should not throw if entity does not have a location', async () => { const todoReader = mockTodoReader([]); const catalogClient = mockCatalogClient({ ...mockEntity, @@ -320,14 +320,14 @@ describe('TodoReaderService', () => { await expect(service.listTodos({ entity: entityName })).rejects.toEqual( expect.objectContaining({ - name: 'InputError', + name: 'Error', message: - 'No entity location annotation found for component:default/my-component', + 'Entity \'component:default/my-component\' is missing location', }), ); }); - it('should throw if entity has an invalid location', async () => { + it('should not throw if entity has an invalid location', async () => { const todoReader = mockTodoReader([]); const catalogClient = mockCatalogClient({ ...mockEntity, @@ -340,15 +340,16 @@ describe('TodoReaderService', () => { }); const service = new TodoReaderService({ todoReader, catalogClient }); - await expect(service.listTodos({ entity: entityName })).rejects.toEqual( - expect.objectContaining({ - name: 'InputError', - message: `Invalid entity location type for component:default/my-component, got 'file'`, - }), + await expect(service.listTodos({ entity: entityName })).resolves.toEqual({ + items: [], + totalCount: 0, + offset: 0, + limit: 10, + } ); }); - it('should throw if entity has an invalid source location', async () => { + it('should not throw if entity has an invalid source location', async () => { const todoReader = mockTodoReader([]); const catalogClient = mockCatalogClient({ ...mockEntity, @@ -361,11 +362,12 @@ describe('TodoReaderService', () => { }); const service = new TodoReaderService({ todoReader, catalogClient }); - await expect(service.listTodos({ entity: entityName })).rejects.toEqual( - expect.objectContaining({ - name: 'InputError', - message: `Invalid entity source location type for component:default/my-component, got 'file'`, - }), + await expect(service.listTodos({ entity: entityName })).resolves.toEqual({ + items: [], + totalCount: 0, + offset: 0, + limit: 10, + } ); }); }); From 5da036264ba7b2114e9e8bb22f1b5c58e3312509 Mon Sep 17 00:00:00 2001 From: LvffY Date: Sat, 2 Apr 2022 17:29:40 +0200 Subject: [PATCH 12/58] =?UTF-8?q?[#10582]=20=E2=9C=A8=20Add=20changeset?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: LvffY (cherry picked from commit e16af648068bd0cc49999c5d078385f15aa7c49b) --- .changeset/gorgeous-donuts-float.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changeset/gorgeous-donuts-float.md diff --git a/.changeset/gorgeous-donuts-float.md b/.changeset/gorgeous-donuts-float.md new file mode 100644 index 0000000000..9016b1117e --- /dev/null +++ b/.changeset/gorgeous-donuts-float.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-todo-backend': patch +--- + +Fix method to get source-location. + +See https://github.com/backstage/backstage/pull/10584 From 4e96e3fdb1ff3813cf1bf4f81970e8485b1312a3 Mon Sep 17 00:00:00 2001 From: LvffY Date: Sat, 2 Apr 2022 17:35:43 +0200 Subject: [PATCH 13/58] =?UTF-8?q?[#10582]=20=F0=9F=93=9D=20Fix=20docs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: LvffY (cherry picked from commit 1fad23ee1ece324b6026b399e8570552a11369cf) --- plugins/todo-backend/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/todo-backend/README.md b/plugins/todo-backend/README.md index 4015087b02..0f4342c19d 100644 --- a/plugins/todo-backend/README.md +++ b/plugins/todo-backend/README.md @@ -52,8 +52,9 @@ async function main() { ## Scanned Files -The included `TodoReaderService` and `TodoScmReader` works by reading source code of to the entity that is being viewed. The location source code is determined by the value of the [`backstage.io/source-location` -](https://backstage.io/docs/features/software-catalog/well-known-annotations#backstageiosource-location) annotation of the entity, and if that is missing it falls back to the [`backstage.io/managed-by-location `](https://backstage.io/docs/features/software-catalog/well-known-annotations#backstageiomanaged-by-location) annotation. Only `url` locations are currently supported, meaning locally configured `file` locations won't work. Also note that dot-files and folders are ignored. +The included `TodoReaderService` and `TodoScmReader` works by getting the entity source location from the catalog. + +The location source code is determined automatically. In case of the source code of the component is not in the same place of the entity YAML file, you can explicitly set the value of the [`backstage.io/source-location`](https://backstage.io/docs/features/software-catalog/well-known-annotations#backstageiosource-location) annotation of the entity, and if that is missing it falls back to the [`backstage.io/managed-by-location `](https://backstage.io/docs/features/software-catalog/well-known-annotations#backstageiomanaged-by-location) annotation. Only `url` locations are currently supported, meaning locally configured `file` locations won't work. Also note that dot-files and folders are ignored. ## Parser Configuration From 3399dfb8c075383b7e2151a6718c704b84adf1e0 Mon Sep 17 00:00:00 2001 From: LvffY Date: Sat, 2 Apr 2022 17:41:48 +0200 Subject: [PATCH 14/58] =?UTF-8?q?[#10582]=20=F0=9F=91=8C=20Pass=20prettier?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: LvffY (cherry picked from commit a103befad1950863049a5711471500690d6eb2bd) --- plugins/todo-backend/README.md | 2 +- .../src/service/TodoReaderService.test.ts | 25 ++++++++----------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/plugins/todo-backend/README.md b/plugins/todo-backend/README.md index 0f4342c19d..4686c2d39f 100644 --- a/plugins/todo-backend/README.md +++ b/plugins/todo-backend/README.md @@ -52,7 +52,7 @@ async function main() { ## Scanned Files -The included `TodoReaderService` and `TodoScmReader` works by getting the entity source location from the catalog. +The included `TodoReaderService` and `TodoScmReader` works by getting the entity source location from the catalog. The location source code is determined automatically. In case of the source code of the component is not in the same place of the entity YAML file, you can explicitly set the value of the [`backstage.io/source-location`](https://backstage.io/docs/features/software-catalog/well-known-annotations#backstageiosource-location) annotation of the entity, and if that is missing it falls back to the [`backstage.io/managed-by-location `](https://backstage.io/docs/features/software-catalog/well-known-annotations#backstageiomanaged-by-location) annotation. Only `url` locations are currently supported, meaning locally configured `file` locations won't work. Also note that dot-files and folders are ignored. diff --git a/plugins/todo-backend/src/service/TodoReaderService.test.ts b/plugins/todo-backend/src/service/TodoReaderService.test.ts index f99a9b7502..b16f0ee669 100644 --- a/plugins/todo-backend/src/service/TodoReaderService.test.ts +++ b/plugins/todo-backend/src/service/TodoReaderService.test.ts @@ -321,8 +321,7 @@ describe('TodoReaderService', () => { await expect(service.listTodos({ entity: entityName })).rejects.toEqual( expect.objectContaining({ name: 'Error', - message: - 'Entity \'component:default/my-component\' is missing location', + message: "Entity 'component:default/my-component' is missing location", }), ); }); @@ -341,12 +340,11 @@ describe('TodoReaderService', () => { const service = new TodoReaderService({ todoReader, catalogClient }); await expect(service.listTodos({ entity: entityName })).resolves.toEqual({ - items: [], - totalCount: 0, - offset: 0, - limit: 10, - } - ); + items: [], + totalCount: 0, + offset: 0, + limit: 10, + }); }); it('should not throw if entity has an invalid source location', async () => { @@ -363,11 +361,10 @@ describe('TodoReaderService', () => { const service = new TodoReaderService({ todoReader, catalogClient }); await expect(service.listTodos({ entity: entityName })).resolves.toEqual({ - items: [], - totalCount: 0, - offset: 0, - limit: 10, - } - ); + items: [], + totalCount: 0, + offset: 0, + limit: 10, + }); }); }); From fe3c72181412f9d591ff87f03468c7dadff4589a Mon Sep 17 00:00:00 2001 From: LvffY Date: Fri, 8 Apr 2022 19:12:00 +0200 Subject: [PATCH 15/58] =?UTF-8?q?[#10582]=20=F0=9F=91=8C=20Fix=20changeset?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See https://github.com/backstage/backstage/pull/10584#discussion_r841507071 Signed-off-by: LvffY (cherry picked from commit bd7e5271b1fe283fc1b304185c0d53115d1da172) --- .changeset/gorgeous-donuts-float.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/.changeset/gorgeous-donuts-float.md b/.changeset/gorgeous-donuts-float.md index 9016b1117e..72a28ba6f9 100644 --- a/.changeset/gorgeous-donuts-float.md +++ b/.changeset/gorgeous-donuts-float.md @@ -3,5 +3,3 @@ --- Fix method to get source-location. - -See https://github.com/backstage/backstage/pull/10584 From 75ab45d8b4d8988d5a52b3c1e0eb6a79d2c786d2 Mon Sep 17 00:00:00 2001 From: LvffY Date: Fri, 8 Apr 2022 19:49:37 +0200 Subject: [PATCH 16/58] =?UTF-8?q?[#10582]=20=F0=9F=91=8C=20Re-add=20tests?= =?UTF-8?q?=20and=20code=20to=20throw=20exceptions=20when=20entity=20type?= =?UTF-8?q?=20is=20not=20url.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See https://github.com/backstage/backstage/pull/10584#discussion_r841505986 See https://github.com/backstage/backstage/pull/10584#discussion_r841502848 Signed-off-by: LvffY (cherry picked from commit 8a986150cc1e96b3150516ef36f24bdd89c55bff) --- .../src/service/TodoReaderService.test.ts | 32 +++++++++---------- .../src/service/TodoReaderService.ts | 11 +++++-- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/plugins/todo-backend/src/service/TodoReaderService.test.ts b/plugins/todo-backend/src/service/TodoReaderService.test.ts index b16f0ee669..3806895666 100644 --- a/plugins/todo-backend/src/service/TodoReaderService.test.ts +++ b/plugins/todo-backend/src/service/TodoReaderService.test.ts @@ -326,45 +326,45 @@ describe('TodoReaderService', () => { ); }); - it('should not throw if entity has an invalid location', async () => { + it('should throw if entity has an invalid location', async () => { const todoReader = mockTodoReader([]); const catalogClient = mockCatalogClient({ ...mockEntity, metadata: { ...mockEntity.metadata, annotations: { - ['backstage.io/managed-by-location']: 'file:../info.yaml', + ['backstage.io/managed-by-location']: 'file:../managed-by-location.yaml', }, }, }); const service = new TodoReaderService({ todoReader, catalogClient }); - await expect(service.listTodos({ entity: entityName })).resolves.toEqual({ - items: [], - totalCount: 0, - offset: 0, - limit: 10, - }); + await expect(service.listTodos({ entity: entityName })).rejects.toEqual( + expect.objectContaining({ + name: 'InputError', + message: `Invalid entity location type for component:default/my-component, got 'file' for location ../managed-by-location.yaml`, + }), + ); }); - it('should not throw if entity has an invalid source location', async () => { + it('should throw if entity has an invalid source location', async () => { const todoReader = mockTodoReader([]); const catalogClient = mockCatalogClient({ ...mockEntity, metadata: { ...mockEntity.metadata, annotations: { - ['backstage.io/source-location']: 'file:../info.yaml', + ['backstage.io/source-location']: 'file:../source-location.yaml', }, }, }); const service = new TodoReaderService({ todoReader, catalogClient }); - await expect(service.listTodos({ entity: entityName })).resolves.toEqual({ - items: [], - totalCount: 0, - offset: 0, - limit: 10, - }); + await expect(service.listTodos({ entity: entityName })).rejects.toEqual( + expect.objectContaining({ + name: 'InputError', + message: `Invalid entity location type for component:default/my-component, got 'file' for location ../source-location.yaml`, + }), + ); }); }); diff --git a/plugins/todo-backend/src/service/TodoReaderService.ts b/plugins/todo-backend/src/service/TodoReaderService.ts index 1b3376dbfd..20d633e409 100644 --- a/plugins/todo-backend/src/service/TodoReaderService.ts +++ b/plugins/todo-backend/src/service/TodoReaderService.ts @@ -71,8 +71,15 @@ export class TodoReaderService implements TodoService { `Entity not found, ${stringifyEntityRef(req.entity)}`, ); } - - const url = getEntitySourceLocation(entity).target; + const entitySourceLocation = getEntitySourceLocation(entity) + if (entitySourceLocation.type !== 'url') { + throw new InputError( + `Invalid entity location type for ${stringifyEntityRef( + entity, + )}, got '${entitySourceLocation.type}' for location ${entitySourceLocation.target}`, + ); + } + const url = entitySourceLocation.target; const todos = await this.todoReader.readTodos({ url }); let limit = req.limit ?? this.defaultPageSize; From 659ef6aaa9949b7ff6d638ae4750927059101111 Mon Sep 17 00:00:00 2001 From: LvffY Date: Fri, 8 Apr 2022 19:56:23 +0200 Subject: [PATCH 17/58] =?UTF-8?q?[#10582]=20=F0=9F=91=8C=20Pass=20prettier?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: LvffY (cherry picked from commit 90efbd7f197c999f7a067bb813ff5b0232307b2f) --- .../todo-backend/src/service/TodoReaderService.test.ts | 3 ++- plugins/todo-backend/src/service/TodoReaderService.ts | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/plugins/todo-backend/src/service/TodoReaderService.test.ts b/plugins/todo-backend/src/service/TodoReaderService.test.ts index 3806895666..6dd14afcb4 100644 --- a/plugins/todo-backend/src/service/TodoReaderService.test.ts +++ b/plugins/todo-backend/src/service/TodoReaderService.test.ts @@ -333,7 +333,8 @@ describe('TodoReaderService', () => { metadata: { ...mockEntity.metadata, annotations: { - ['backstage.io/managed-by-location']: 'file:../managed-by-location.yaml', + ['backstage.io/managed-by-location']: + 'file:../managed-by-location.yaml', }, }, }); diff --git a/plugins/todo-backend/src/service/TodoReaderService.ts b/plugins/todo-backend/src/service/TodoReaderService.ts index 20d633e409..35fd76b8be 100644 --- a/plugins/todo-backend/src/service/TodoReaderService.ts +++ b/plugins/todo-backend/src/service/TodoReaderService.ts @@ -71,12 +71,12 @@ export class TodoReaderService implements TodoService { `Entity not found, ${stringifyEntityRef(req.entity)}`, ); } - const entitySourceLocation = getEntitySourceLocation(entity) + const entitySourceLocation = getEntitySourceLocation(entity); if (entitySourceLocation.type !== 'url') { throw new InputError( - `Invalid entity location type for ${stringifyEntityRef( - entity, - )}, got '${entitySourceLocation.type}' for location ${entitySourceLocation.target}`, + `Invalid entity location type for ${stringifyEntityRef(entity)}, got '${ + entitySourceLocation.type + }' for location ${entitySourceLocation.target}`, ); } const url = entitySourceLocation.target; From bb0e30bb940aca1af0bfed83983523d39c709ed4 Mon Sep 17 00:00:00 2001 From: daftgopher Date: Fri, 8 Apr 2022 15:22:38 -0400 Subject: [PATCH 18/58] Update adopters file Signed-off-by: daftgopher --- ADOPTERS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ADOPTERS.md b/ADOPTERS.md index ce5b2b70ef..006dc071cd 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -26,7 +26,7 @@ _If you're using Backstage in your organization, please try to add your company | [Acast.com](https://acast.com) | [Olle Lundberg](https://github.com/lndbrg) | Developer portal with tech docs, service catalog and a bunch of other internal tooling | | [Lunar](https://lunar.app) | [Jacob Valdemar](https://github.com/JacobValdemar) | Internal developer portal for service overview and insights, API documentation, technical guides, onboarding guides and RFC's. | | [Trendyol](https://trendyol.com) | [Gamze Senturk](https://github.com/gmzsenturk), [Mert Can Bilgic](https://github.com/mertcb) | The Developer Portal has been called `Pandora`. Provides an overview of Trendyol tech ecosystem. TechDocs, Catalog, Custom Plugins and Theme. | -| [Peloton](https://www.onepeloton.com/) | [Jim Haughwout](https://github.com/JimHaughwout) | Creating our first developer portal and tech-docs. Exploring Service Catalog, Tech Insights and Cost Insights as well. | +| [Peloton](https://www.onepeloton.com/) | [Matt Waldron](https://github.com/daftgopher) | Creating our first developer portal and tech-docs. Exploring Service Catalog, Tech Insights and Cost Insights as well. | | [TELUS](https://telus.com) | [Seb Barre](https://github.com/sbarre) | The Go-to place to find answers about development and delivery at TELUS. | | [Brex](https://www.brex.com/) | [Vamsi Chitters](https://github.com/vamsikc) | A centralized UI to understand how a service fits in the whole Brex architecture and manage a team’s engineering dependencies. | | [Oriflame](https://www.oriflame.com/) | [Oriflame](https://github.com/oriflame) | Internal developer portal for services, single page apps and packages overview, API documentation, technical guides, tech-radar and more. | From c2b79c12dedc97134026b8ee18e6998fe5206a14 Mon Sep 17 00:00:00 2001 From: Rogerio Angeliski Date: Sat, 9 Apr 2022 09:22:36 -0300 Subject: [PATCH 19/58] Update docs to refer new prop Signed-off-by: Rogerio Angeliski --- plugins/tech-insights/README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugins/tech-insights/README.md b/plugins/tech-insights/README.md index 5f7d7ad4e5..a305ef5dc7 100644 --- a/plugins/tech-insights/README.md +++ b/plugins/tech-insights/README.md @@ -38,6 +38,10 @@ const serviceEntityPage = ( title="Customized title for the scorecard" description="Small description about scorecards" /> + ... @@ -46,6 +50,8 @@ const serviceEntityPage = ( It is not obligatory to pass title and description props to `EntityTechInsightsScorecardContent`. If those are left out, default values from `defaultCheckResultRenderers` in `CheckResultRenderer` will be taken, hence `Boolean scorecard` and `This card represents an overview of default boolean Backstage checks`. +You can pass an array `checksId` as a prop with the [Fact Retrievers ids](../tech-insights-backend#creating-fact-retrievers) to limit which checks you want to show in this card, If you don't pass, the default value is show all checks. + ## Boolean Scorecard Example If you follow the [Backend Example](https://github.com/backstage/backstage/tree/master/plugins/tech-insights-backend#backend-example), once the needed facts have been generated the boolean scorecard will look like this: From f26cf63878366afee00ea81766b5d6fac4cc5ca1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 9 Apr 2022 12:31:39 +0000 Subject: [PATCH 20/58] build(deps-dev): bump @types/jest-when from 2.7.2 to 3.5.0 Bumps [@types/jest-when](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest-when) from 2.7.2 to 3.5.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest-when) --- updated-dependencies: - dependency-name: "@types/jest-when" dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .changeset/dependabot-699dc23.md | 5 +++++ plugins/kafka-backend/package.json | 2 +- yarn.lock | 8 ++++---- 3 files changed, 10 insertions(+), 5 deletions(-) create mode 100644 .changeset/dependabot-699dc23.md diff --git a/.changeset/dependabot-699dc23.md b/.changeset/dependabot-699dc23.md new file mode 100644 index 0000000000..b73b0eab46 --- /dev/null +++ b/.changeset/dependabot-699dc23.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-kafka-backend': patch +--- + +build(deps-dev): bump `@types/jest-when` from 2.7.2 to 3.5.0 diff --git a/plugins/kafka-backend/package.json b/plugins/kafka-backend/package.json index 4deeefc788..732fc30927 100644 --- a/plugins/kafka-backend/package.json +++ b/plugins/kafka-backend/package.json @@ -48,7 +48,7 @@ }, "devDependencies": { "@backstage/cli": "^0.17.0-next.1", - "@types/jest-when": "^2.7.2", + "@types/jest-when": "^3.5.0", "@types/lodash": "^4.14.151", "jest-when": "^3.1.0", "supertest": "^6.1.3" diff --git a/yarn.lock b/yarn.lock index 37046a1f16..e469f8432b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6224,10 +6224,10 @@ dependencies: "@types/node" "*" -"@types/jest-when@^2.7.2": - version "2.7.2" - resolved "https://registry.npmjs.org/@types/jest-when/-/jest-when-2.7.2.tgz#619fbc5f623bcd0b29efde0e4993c7f0d50d026d" - integrity sha512-vOtj0cev6vO1VX7Jbfg/qvy+sfLI64STsHbKVkggK+1kd11rcMGzFpZKBxUvQfsm4JRULCBISu+qrfs7fYZFGg== +"@types/jest-when@^3.5.0": + version "3.5.0" + resolved "https://registry.npmjs.org/@types/jest-when/-/jest-when-3.5.0.tgz#6a573cd521da131e6801f0991b4f1d4dee2ebab5" + integrity sha512-rNUuZ3Mn/HDzpImPXDeOtW18zqyerPoOS2aKU0zUFbirWgJ7sN7LnRv73RmbBQ/uzw28sxf/nUofxbhJ5DWB0w== dependencies: "@types/jest" "*" From f95c796c98abf0ccbdeaa66bcfafbe7f1d944395 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 9 Apr 2022 13:22:26 +0000 Subject: [PATCH 21/58] build(deps-dev): bump @types/lodash from 4.14.178 to 4.14.181 Bumps [@types/lodash](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/lodash) from 4.14.178 to 4.14.181. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/lodash) --- updated-dependencies: - dependency-name: "@types/lodash" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index e469f8432b..8d38361061 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6325,9 +6325,9 @@ "@types/node" "*" "@types/lodash@^4.14.151", "@types/lodash@^4.14.173", "@types/lodash@^4.14.175": - version "4.14.178" - resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.178.tgz#341f6d2247db528d4a13ddbb374bcdc80406f4f8" - integrity sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw== + version "4.14.181" + resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.181.tgz#d1d3740c379fda17ab175165ba04e2d03389385d" + integrity sha512-n3tyKthHJbkiWhDZs3DkhkCzt2MexYHXlX0td5iMplyfwketaOeKboEVBqzceH7juqvEg3q5oUoBFxSLu7zFag== "@types/long@^4.0.0", "@types/long@^4.0.1": version "4.0.1" From fedff63fd61f74170b5cec2908ad3ff6aea6b8d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Sat, 9 Apr 2022 15:49:45 +0200 Subject: [PATCH 22/58] update dependencies needed in the docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- docs/integrations/github/discovery.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/integrations/github/discovery.md b/docs/integrations/github/discovery.md index 46e054364f..1cbf8905a2 100644 --- a/docs/integrations/github/discovery.md +++ b/docs/integrations/github/discovery.md @@ -16,11 +16,12 @@ catalog. You will have to add the processors in the catalog initialization code of your backend. They are not installed by default, therefore you have to add a -dependency to `@backstage/plugin-catalog-backend-module-github` to your backend -package. +dependency on `@backstage/plugin-catalog-backend-module-github` to your backend +package, plus `@backstage/integration` for the basic credentials management: ```bash # From your Backstage root directory +yarn add --cwd packages/backend @backstage/integration yarn add --cwd packages/backend @backstage/plugin-catalog-backend-module-github ``` From 564724023795523030add1a8327e0cb9610fb6ed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Apr 2022 04:12:39 +0000 Subject: [PATCH 23/58] build(deps): bump @testing-library/jest-dom from 5.16.3 to 5.16.4 Bumps [@testing-library/jest-dom](https://github.com/testing-library/jest-dom) from 5.16.3 to 5.16.4. - [Release notes](https://github.com/testing-library/jest-dom/releases) - [Changelog](https://github.com/testing-library/jest-dom/blob/main/CHANGELOG.md) - [Commits](https://github.com/testing-library/jest-dom/compare/v5.16.3...v5.16.4) --- updated-dependencies: - dependency-name: "@testing-library/jest-dom" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index e469f8432b..d0224678e2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5546,9 +5546,9 @@ pretty-format "^27.0.2" "@testing-library/jest-dom@^5.10.1": - version "5.16.3" - resolved "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.3.tgz#b76851a909586113c20486f1679ffb4d8ec27bfa" - integrity sha512-u5DfKj4wfSt6akfndfu1eG06jsdyA/IUrlX2n3pyq5UXgXMhXY+NJb8eNK/7pqPWAhCKsCGWDdDO0zKMKAYkEA== + version "5.16.4" + resolved "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.4.tgz#938302d7b8b483963a3ae821f1c0808f872245cd" + integrity sha512-Gy+IoFutbMQcky0k+bqqumXZ1cTGswLsFqmNLzNdSKkU9KGV2u9oXhukCbbJ9/LRPKiqwxEE8VpV/+YZlfkPUA== dependencies: "@babel/runtime" "^7.9.2" "@types/testing-library__jest-dom" "^5.9.1" From 2492b135e0d5284a4680580bb800e4e7145beff7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Apr 2022 04:13:17 +0000 Subject: [PATCH 24/58] build(deps): bump selfsigned from 2.0.0 to 2.0.1 Bumps [selfsigned](https://github.com/jfromaniello/selfsigned) from 2.0.0 to 2.0.1. - [Release notes](https://github.com/jfromaniello/selfsigned/releases) - [Commits](https://github.com/jfromaniello/selfsigned/compare/v2.0.0...v2.0.1) --- updated-dependencies: - dependency-name: selfsigned dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- yarn.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/yarn.lock b/yarn.lock index e469f8432b..2ae061d080 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18425,10 +18425,10 @@ node-fetch@2.6.7, node-fetch@^2.3.0, node-fetch@^2.6.0, node-fetch@^2.6.1, node- dependencies: whatwg-url "^5.0.0" -node-forge@^1.0.0, node-forge@^1.2.0: - version "1.3.0" - resolved "https://registry.npmjs.org/node-forge/-/node-forge-1.3.0.tgz#37a874ea723855f37db091e6c186e5b67a01d4b2" - integrity sha512-08ARB91bUi6zNKzVmaj3QO7cr397uiDT2nJ63cHjyNtCTWIgvS47j3eT0WfzUwS9+6Z5YshRaoasFkXCKrIYbA== +node-forge@^1, node-forge@^1.0.0: + version "1.3.1" + resolved "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" + integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== node-gyp@^5.0.2: version "5.1.0" @@ -22260,11 +22260,11 @@ select-hose@^2.0.0: integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= selfsigned@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/selfsigned/-/selfsigned-2.0.0.tgz#e927cd5377cbb0a1075302cff8df1042cc2bce5b" - integrity sha512-cUdFiCbKoa1mZ6osuJs2uDHrs0k0oprsKveFiiaBKCNq3SYyb5gs2HxhQyDNLCmL51ZZThqi4YNDpCK6GOP1iQ== + version "2.0.1" + resolved "https://registry.npmjs.org/selfsigned/-/selfsigned-2.0.1.tgz#8b2df7fa56bf014d19b6007655fff209c0ef0a56" + integrity sha512-LmME957M1zOsUhG+67rAjKfiWFox3SBxE/yymatMZsAx+oMrJ0YQ8AToOnyCm7xbeg2ep37IHLxdu0o2MavQOQ== dependencies: - node-forge "^1.2.0" + node-forge "^1" semver-diff@^3.1.1: version "3.1.1" From 652c87a4839b829b896c1fb1615dac0ba195b266 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Apr 2022 04:30:24 +0000 Subject: [PATCH 25/58] build(deps-dev): bump @types/supertest from 2.0.11 to 2.0.12 Bumps [@types/supertest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/supertest) from 2.0.11 to 2.0.12. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/supertest) --- updated-dependencies: - dependency-name: "@types/supertest" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index e469f8432b..a511002bea 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6830,9 +6830,9 @@ "@types/node" "*" "@types/supertest@^2.0.8": - version "2.0.11" - resolved "https://registry.npmjs.org/@types/supertest/-/supertest-2.0.11.tgz#2e70f69f220bc77b4f660d72c2e1a4231f44a77d" - integrity sha512-uci4Esokrw9qGb9bvhhSVEjd6rkny/dk5PK/Qz4yxKiyppEI+dOPlNrZBahE3i+PoKFYyDxChVXZ/ysS/nrm1Q== + version "2.0.12" + resolved "https://registry.npmjs.org/@types/supertest/-/supertest-2.0.12.tgz#ddb4a0568597c9aadff8dbec5b2e8fddbe8692fc" + integrity sha512-X3HPWTwXRerBZS7Mo1k6vMVR1Z6zmJcDVn5O/31whe0tnjE4te6ZJSJGq1RiqHPjzPdMTfjCFogDJmwng9xHaQ== dependencies: "@types/superagent" "*" From e1648038ccf235768d2ea7470f8b204fcde58aa2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Apr 2022 04:31:06 +0000 Subject: [PATCH 26/58] build(deps-dev): bump @changesets/cli from 2.21.0 to 2.22.0 Bumps [@changesets/cli](https://github.com/changesets/changesets) from 2.21.0 to 2.22.0. - [Release notes](https://github.com/changesets/changesets/releases) - [Changelog](https://github.com/changesets/changesets/blob/main/docs/modifying-changelog-format.md) - [Commits](https://github.com/changesets/changesets/compare/@changesets/cli@2.21.0...@changesets/cli@2.22.0) --- updated-dependencies: - dependency-name: "@changesets/cli" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- yarn.lock | 166 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 86 insertions(+), 80 deletions(-) diff --git a/yarn.lock b/yarn.lock index e469f8432b..620a03c6b6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1617,16 +1617,16 @@ resolved "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.0.tgz#fe364f025ba74f6de6c837a84ef44bdb1d61e68f" integrity sha512-mgmE7XBYY/21erpzhexk4Cj1cyTQ9LzvnTxtzM17BJ7ERMNE6W72mQRo0I1Ud8eFJ+RVVIcBNhLFZ3GX4XFz5w== -"@changesets/apply-release-plan@^5.0.5": - version "5.0.5" - resolved "https://registry.npmjs.org/@changesets/apply-release-plan/-/apply-release-plan-5.0.5.tgz#d67b1e022c876d18d887f3c475a3abcad9944b68" - integrity sha512-CxL9dkhzjHiVmXCyHgsLCQj7i/coFTMv/Yy0v6BC5cIWZkQml+lf7zvQqAcFXwY7b54HxRWZPku02XFB53Q0Uw== +"@changesets/apply-release-plan@^6.0.0": + version "6.0.0" + resolved "https://registry.npmjs.org/@changesets/apply-release-plan/-/apply-release-plan-6.0.0.tgz#6c663ff99d919bba3902343d76c35cbbbb046520" + integrity sha512-gp6nIdVdfYdwKww2+f8whckKmvfE4JEm4jJgBhTmooi0uzHWhnxvk6JIzQi89qEAMINN0SeVNnXiAtbFY0Mj3w== dependencies: "@babel/runtime" "^7.10.4" - "@changesets/config" "^1.7.0" + "@changesets/config" "^2.0.0" "@changesets/get-version-range-type" "^0.3.2" - "@changesets/git" "^1.3.1" - "@changesets/types" "^4.1.0" + "@changesets/git" "^1.3.2" + "@changesets/types" "^5.0.0" "@manypkg/get-packages" "^1.1.3" detect-indent "^6.0.0" fs-extra "^7.0.1" @@ -1636,44 +1636,44 @@ resolve-from "^5.0.0" semver "^5.4.1" -"@changesets/assemble-release-plan@^5.1.0": - version "5.1.0" - resolved "https://registry.npmjs.org/@changesets/assemble-release-plan/-/assemble-release-plan-5.1.0.tgz#0fcb18253998e3bc037a554874de43bcc58c4840" - integrity sha512-iYlqffCMhcwZ+6Cv8cimf10OBGYXQKufBI7J6htpRgCV2nT99RKXEjbYOtrXWKQqzu0XxOsk15apSEwjZN0JRw== +"@changesets/assemble-release-plan@^5.1.2": + version "5.1.2" + resolved "https://registry.npmjs.org/@changesets/assemble-release-plan/-/assemble-release-plan-5.1.2.tgz#63ed3a00f62b5af08a82e83801a252ac9726c625" + integrity sha512-nOFyDw4APSkY/vh5WNwGEtThPgEjVShp03PKVdId6wZTJALVcAALCSLmDRfeqjE2z9EsGJb7hZdDlziKlnqZgw== dependencies: "@babel/runtime" "^7.10.4" "@changesets/errors" "^0.1.4" - "@changesets/get-dependents-graph" "^1.3.1" - "@changesets/types" "^4.1.0" + "@changesets/get-dependents-graph" "^1.3.2" + "@changesets/types" "^5.0.0" "@manypkg/get-packages" "^1.1.3" semver "^5.4.1" -"@changesets/changelog-git@^0.1.10": - version "0.1.10" - resolved "https://registry.npmjs.org/@changesets/changelog-git/-/changelog-git-0.1.10.tgz#df616e92671082a7976381280b4af98ff3a7067d" - integrity sha512-4t7zqPOv3aDZp4Y+AyDhiOG2ypaUXDpOz+MT1wOk3uSZNv78AaDByam0hdk5kfYuH1RlMecWU4/U5lO1ZL5eaA== +"@changesets/changelog-git@^0.1.11": + version "0.1.11" + resolved "https://registry.npmjs.org/@changesets/changelog-git/-/changelog-git-0.1.11.tgz#80eb45d3562aba2164f25ccc31ac97b9dcd1ded3" + integrity sha512-sWJvAm+raRPeES9usNpZRkooeEB93lOpUN0Lmjz5vhVAb7XGIZrHEJ93155bpE1S0c4oJ5Di9ZWgzIwqhWP/Wg== dependencies: - "@changesets/types" "^4.1.0" + "@changesets/types" "^5.0.0" "@changesets/cli@^2.14.0": - version "2.21.0" - resolved "https://registry.npmjs.org/@changesets/cli/-/cli-2.21.0.tgz#b689f91ed908150efc06e0985e6b4cfbd9aea3a3" - integrity sha512-cJXRg28MmF9VbQrlwSjpY4AJA2xZUbXFCpQ3kFmX0IeppO7wknZ2QfocAhIqwM828t8d3R4Zpi5xnvJ/crIcQw== + version "2.22.0" + resolved "https://registry.npmjs.org/@changesets/cli/-/cli-2.22.0.tgz#3bdbfb4a7a81ef37f63114e77da84e23f906b763" + integrity sha512-4bA3YoBkd5cm5WUxmrR2N9WYE7EeQcM+R3bVYMUj2NvffkQVpU3ckAI+z8UICoojq+HRl2OEwtz+S5UBmYY4zw== dependencies: "@babel/runtime" "^7.10.4" - "@changesets/apply-release-plan" "^5.0.5" - "@changesets/assemble-release-plan" "^5.1.0" - "@changesets/changelog-git" "^0.1.10" - "@changesets/config" "^1.7.0" + "@changesets/apply-release-plan" "^6.0.0" + "@changesets/assemble-release-plan" "^5.1.2" + "@changesets/changelog-git" "^0.1.11" + "@changesets/config" "^2.0.0" "@changesets/errors" "^0.1.4" - "@changesets/get-dependents-graph" "^1.3.1" - "@changesets/get-release-plan" "^3.0.6" - "@changesets/git" "^1.3.1" + "@changesets/get-dependents-graph" "^1.3.2" + "@changesets/get-release-plan" "^3.0.8" + "@changesets/git" "^1.3.2" "@changesets/logger" "^0.0.5" - "@changesets/pre" "^1.0.10" - "@changesets/read" "^0.5.4" - "@changesets/types" "^4.1.0" - "@changesets/write" "^0.1.7" + "@changesets/pre" "^1.0.11" + "@changesets/read" "^0.5.5" + "@changesets/types" "^5.0.0" + "@changesets/write" "^0.1.8" "@manypkg/get-packages" "^1.1.3" "@types/is-ci" "^3.0.0" "@types/semver" "^6.0.0" @@ -1687,20 +1687,21 @@ outdent "^0.5.0" p-limit "^2.2.0" preferred-pm "^3.0.0" + resolve-from "^5.0.0" semver "^5.4.1" spawndamnit "^2.0.0" term-size "^2.1.0" tty-table "^2.8.10" -"@changesets/config@^1.7.0": - version "1.7.0" - resolved "https://registry.npmjs.org/@changesets/config/-/config-1.7.0.tgz#18353f88ea8153d7f1fb7c321a3fe8667035eddb" - integrity sha512-Ctk6ZO5Ay6oZ95bbKXyA2a1QG0jQUePaGCY6BKkZtUG4PgysesfmiQOPgOY5OsRMt8exJeo6l+DJ75YiKmh0rQ== +"@changesets/config@^2.0.0": + version "2.0.0" + resolved "https://registry.npmjs.org/@changesets/config/-/config-2.0.0.tgz#1770fdfeba2155cf07154c37e96b55cbd27969f0" + integrity sha512-r5bIFY6CN3K6SQ+HZbjyE3HXrBIopONR47mmX7zUbORlybQXtympq9rVAOzc0Oflbap8QeIexc+hikfZoREXDg== dependencies: "@changesets/errors" "^0.1.4" - "@changesets/get-dependents-graph" "^1.3.1" + "@changesets/get-dependents-graph" "^1.3.2" "@changesets/logger" "^0.0.5" - "@changesets/types" "^4.1.0" + "@changesets/types" "^5.0.0" "@manypkg/get-packages" "^1.1.3" fs-extra "^7.0.1" micromatch "^4.0.2" @@ -1712,28 +1713,28 @@ dependencies: extendable-error "^0.1.5" -"@changesets/get-dependents-graph@^1.3.1": - version "1.3.1" - resolved "https://registry.npmjs.org/@changesets/get-dependents-graph/-/get-dependents-graph-1.3.1.tgz#f1ebadbd4e17bb2b987c4542a588e0ee9f2e829a" - integrity sha512-HwUs8U0XK/ZqCQon1/80jJEyswS8JVmTiHTZslrTpuavyhhhxrSpO1eVCdKgaVHBRalOw3gRzdS3uzkmqYsQSQ== +"@changesets/get-dependents-graph@^1.3.2": + version "1.3.2" + resolved "https://registry.npmjs.org/@changesets/get-dependents-graph/-/get-dependents-graph-1.3.2.tgz#f3ec7ce75f4afb6e3e4b6a87fde065f552c85998" + integrity sha512-tsqA6qZRB86SQuApSoDvI8yEWdyIlo/WLI4NUEdhhxLMJ0dapdeT6rUZRgSZzK1X2nv5YwR0MxQBbDAiDibKrg== dependencies: - "@changesets/types" "^4.1.0" + "@changesets/types" "^5.0.0" "@manypkg/get-packages" "^1.1.3" chalk "^2.1.0" fs-extra "^7.0.1" semver "^5.4.1" -"@changesets/get-release-plan@^3.0.6": - version "3.0.6" - resolved "https://registry.npmjs.org/@changesets/get-release-plan/-/get-release-plan-3.0.6.tgz#15aac108b9d0f139841562c9372d8cfd738503dc" - integrity sha512-HpPyr8y6xkihy3rONLZ6OtfgYq88NotidPAuS3nwMeZjLHiIVLyejR2+/5q717f6HKcrATxAjTwMAcjl7X/uzA== +"@changesets/get-release-plan@^3.0.8": + version "3.0.8" + resolved "https://registry.npmjs.org/@changesets/get-release-plan/-/get-release-plan-3.0.8.tgz#2ac7c4f7903aedede3d27af66311ad1db7937e5d" + integrity sha512-TJYiWNuP0Lzu2dL/KHuk75w7TkiE5HqoYirrXF7SJIxkhlgH9toQf2C7IapiFTObtuF1qDN8HJAX1CuIOwXldg== dependencies: "@babel/runtime" "^7.10.4" - "@changesets/assemble-release-plan" "^5.1.0" - "@changesets/config" "^1.7.0" - "@changesets/pre" "^1.0.10" - "@changesets/read" "^0.5.4" - "@changesets/types" "^4.1.0" + "@changesets/assemble-release-plan" "^5.1.2" + "@changesets/config" "^2.0.0" + "@changesets/pre" "^1.0.11" + "@changesets/read" "^0.5.5" + "@changesets/types" "^5.0.0" "@manypkg/get-packages" "^1.1.3" "@changesets/get-version-range-type@^0.3.2": @@ -1741,14 +1742,14 @@ resolved "https://registry.npmjs.org/@changesets/get-version-range-type/-/get-version-range-type-0.3.2.tgz#8131a99035edd11aa7a44c341cbb05e668618c67" integrity sha512-SVqwYs5pULYjYT4op21F2pVbcrca4qA/bAA3FmFXKMN7Y+HcO8sbZUTx3TAy2VXulP2FACd1aC7f2nTuqSPbqg== -"@changesets/git@^1.3.1": - version "1.3.1" - resolved "https://registry.npmjs.org/@changesets/git/-/git-1.3.1.tgz#e86b4d2b28acdf9bc8949031027a9ac12420b99e" - integrity sha512-yg60QUi38VA0XGXdBy9SRYJhs8xJHE97Z1CaB/hFyByBlh5k1i+avFNBvvw66MsoT/aiml6y9scIG6sC8R5mfg== +"@changesets/git@^1.3.2": + version "1.3.2" + resolved "https://registry.npmjs.org/@changesets/git/-/git-1.3.2.tgz#336051d9a6d965806b1bc473559a9a2cc70773a6" + integrity sha512-p5UL+urAg0Nnpt70DLiBe2iSsMcDubTo9fTOD/61krmcJ466MGh71OHwdAwu1xG5+NKzeysdy1joRTg8CXcEXA== dependencies: "@babel/runtime" "^7.10.4" "@changesets/errors" "^0.1.4" - "@changesets/types" "^4.1.0" + "@changesets/types" "^5.0.0" "@manypkg/get-packages" "^1.1.3" is-subdir "^1.1.1" spawndamnit "^2.0.0" @@ -1760,51 +1761,56 @@ dependencies: chalk "^2.1.0" -"@changesets/parse@^0.3.12": - version "0.3.12" - resolved "https://registry.npmjs.org/@changesets/parse/-/parse-0.3.12.tgz#60569bb39ad4ffe47fc01d431613ce5c42e6590f" - integrity sha512-FOBz2L1dT9PcvyQU1Qp2sQ0B4Jw7EgRDAKFVzAQwhzXqCq03TcE7vgKU6VSksCJAioMYDowdVVHNnv/Uak6yZQ== +"@changesets/parse@^0.3.13": + version "0.3.13" + resolved "https://registry.npmjs.org/@changesets/parse/-/parse-0.3.13.tgz#82788c1fc18da4750b07357a7a06142d0d975aa1" + integrity sha512-wh9Ifa0dungY6d2nMz6XxF6FZ/1I7j+mEgPAqrIyKS64nifTh1Ua82qKKMMK05CL7i4wiB2NYc3SfnnCX3RVeA== dependencies: - "@changesets/types" "^4.1.0" + "@changesets/types" "^5.0.0" js-yaml "^3.13.1" -"@changesets/pre@^1.0.10": - version "1.0.10" - resolved "https://registry.npmjs.org/@changesets/pre/-/pre-1.0.10.tgz#e677031f271cdab8443b21e0b3cda036a3919c30" - integrity sha512-cZC1C1wTSC17/TcTWivAQ4LAXz5jEYDuy3UeZiBz1wnTTzMHyTHLLwJi60juhl4hawXunDLw0mwZkcpS8Ivitg== +"@changesets/pre@^1.0.11": + version "1.0.11" + resolved "https://registry.npmjs.org/@changesets/pre/-/pre-1.0.11.tgz#46a56790fdceabd03407559bbf91340c8e83fb6a" + integrity sha512-CXZnt4SV9waaC9cPLm7818+SxvLKIDHUxaiTXnJYDp1c56xIexx1BNfC1yMuOdzO2a3rAIcZua5Odxr3dwSKfg== dependencies: "@babel/runtime" "^7.10.4" "@changesets/errors" "^0.1.4" - "@changesets/types" "^4.1.0" + "@changesets/types" "^5.0.0" "@manypkg/get-packages" "^1.1.3" fs-extra "^7.0.1" -"@changesets/read@^0.5.4": - version "0.5.4" - resolved "https://registry.npmjs.org/@changesets/read/-/read-0.5.4.tgz#c6dc6ab00c4f70f2ce6766433d92eebde1b00e7a" - integrity sha512-12dTx+p5ztFs9QgJDGHRHR6HzTIbHct9S4lK2I/i6Qkz1cNfAPVIbdoMCdbPIWeLank9muMUjiiFmCWJD7tQIg== +"@changesets/read@^0.5.5": + version "0.5.5" + resolved "https://registry.npmjs.org/@changesets/read/-/read-0.5.5.tgz#9ed90ef3e9f1ba3436ba5580201854a3f4163058" + integrity sha512-bzonrPWc29Tsjvgh+8CqJ0apQOwWim0zheeD4ZK44ApSa/GudnZJTODtA3yNOOuQzeZmL0NUebVoHIurtIkA7w== dependencies: "@babel/runtime" "^7.10.4" - "@changesets/git" "^1.3.1" + "@changesets/git" "^1.3.2" "@changesets/logger" "^0.0.5" - "@changesets/parse" "^0.3.12" - "@changesets/types" "^4.1.0" + "@changesets/parse" "^0.3.13" + "@changesets/types" "^5.0.0" chalk "^2.1.0" fs-extra "^7.0.1" p-filter "^2.1.0" -"@changesets/types@^4.0.1", "@changesets/types@^4.1.0": +"@changesets/types@^4.0.1": version "4.1.0" resolved "https://registry.npmjs.org/@changesets/types/-/types-4.1.0.tgz#fb8f7ca2324fd54954824e864f9a61a82cb78fe0" integrity sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw== -"@changesets/write@^0.1.7": - version "0.1.7" - resolved "https://registry.npmjs.org/@changesets/write/-/write-0.1.7.tgz#671def0d871cf5970c5b2f766f0ac4b19ecf1ddb" - integrity sha512-6r+tc6u2l5BBIwEAh7ivRYWFir+XKiw0q/6Hx6NJA4dSN5fNu9uyWRQ+IMHCllD9dBcsh+e79sOepc+xT8l28g== +"@changesets/types@^5.0.0": + version "5.0.0" + resolved "https://registry.npmjs.org/@changesets/types/-/types-5.0.0.tgz#d5eb52d074bc0358ce47d54bca54370b907812a0" + integrity sha512-IT1kBLSbAgTS4WtpU6P5ko054hq12vk4tgeIFRVE7Vnm4a/wgbNvBalgiKP0MjEXbCkZbItiGQHkCGxYWR55sA== + +"@changesets/write@^0.1.8": + version "0.1.8" + resolved "https://registry.npmjs.org/@changesets/write/-/write-0.1.8.tgz#feed408f644c496bc52afc4dd1353670b4152ecb" + integrity sha512-oIHeFVMuP6jf0TPnKPpaFpvvAf3JBc+s2pmVChbeEgQTBTALoF51Z9kqxQfG4XONZPHZnqkmy564c7qohhhhTQ== dependencies: "@babel/runtime" "^7.10.4" - "@changesets/types" "^4.1.0" + "@changesets/types" "^5.0.0" fs-extra "^7.0.1" human-id "^1.0.2" prettier "^1.19.1" From 683dfa0c6403d4b1d87368bb835aa753e30dc641 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Apr 2022 04:39:10 +0000 Subject: [PATCH 27/58] build(deps-dev): bump @storybook/addon-links in /storybook Bumps [@storybook/addon-links](https://github.com/storybookjs/storybook/tree/HEAD/addons/links) from 6.4.20 to 6.4.21. - [Release notes](https://github.com/storybookjs/storybook/releases) - [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md) - [Commits](https://github.com/storybookjs/storybook/commits/v6.4.21/addons/links) --- updated-dependencies: - dependency-name: "@storybook/addon-links" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- storybook/package.json | 2 +- storybook/yarn.lock | 117 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 109 insertions(+), 10 deletions(-) diff --git a/storybook/package.json b/storybook/package.json index d5b54d193d..87c627ac4f 100644 --- a/storybook/package.json +++ b/storybook/package.json @@ -17,7 +17,7 @@ "devDependencies": { "@storybook/addon-a11y": "^6.4.20", "@storybook/addon-actions": "^6.4.20", - "@storybook/addon-links": "^6.4.20", + "@storybook/addon-links": "^6.4.21", "@storybook/addon-storysource": "^6.4.20", "@storybook/addons": "^6.4.20", "@storybook/react": "^6.4.20", diff --git a/storybook/yarn.lock b/storybook/yarn.lock index 82520ab5f5..fb7aa071fe 100644 --- a/storybook/yarn.lock +++ b/storybook/yarn.lock @@ -1356,16 +1356,16 @@ util-deprecate "^1.0.2" uuid-browser "^3.1.0" -"@storybook/addon-links@^6.4.20": - version "6.4.20" - resolved "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-6.4.20.tgz#7e845a20deece65e7e684433d4c66a6ad61da52c" - integrity sha512-TyRuEd/3yRn2N9xasCKuE2bsY0dTRjAquGeg5WEtvHvr8V6QBLYAC4caXwPxIHSTcRQyO5IYYiVzEJ/+219neA== +"@storybook/addon-links@^6.4.21": + version "6.4.21" + resolved "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-6.4.21.tgz#7251406c3060b63684f4de56799385f3675867c6" + integrity sha512-KajbsVAmCLVSKsrPnUEsfWuD5V0lbNBAtdil0EiOqWZU0r3ch92aSMh6H13zfT+lEPlh0PVLKamHur1js1iXGQ== dependencies: - "@storybook/addons" "6.4.20" - "@storybook/client-logger" "6.4.20" - "@storybook/core-events" "6.4.20" + "@storybook/addons" "6.4.21" + "@storybook/client-logger" "6.4.21" + "@storybook/core-events" "6.4.21" "@storybook/csf" "0.0.2--canary.87bc651.0" - "@storybook/router" "6.4.20" + "@storybook/router" "6.4.21" "@types/qs" "^6.9.5" core-js "^3.8.2" global "^4.4.0" @@ -1394,7 +1394,7 @@ react-syntax-highlighter "^13.5.3" regenerator-runtime "^0.13.7" -"@storybook/addons@6.4.20", "@storybook/addons@^6.4.20": +"@storybook/addons@6.4.20": version "6.4.20" resolved "https://registry.npmjs.org/@storybook/addons/-/addons-6.4.20.tgz#bbf568b7c4c5a25ef296f285aef0299998ec5933" integrity sha512-NbsLjDSkE9v2fOr0M7r2hpdYnlYs789ALkXemdTz2y0NUYSPdRfzVVQNXWrgmXivWQRL0aJ3bOjCOc668PPYjg== @@ -1411,6 +1411,23 @@ global "^4.4.0" regenerator-runtime "^0.13.7" +"@storybook/addons@6.4.21", "@storybook/addons@^6.4.20": + version "6.4.21" + resolved "https://registry.npmjs.org/@storybook/addons/-/addons-6.4.21.tgz#a0081d167eda8a30b2206ccabfe75abae0bb6b58" + integrity sha512-TFLv4FyqP5SBOHEqE6tiW+2++HngkyQ2KRbHICC7khQgRqDkrwvrdKZwzF29igseglhSmftpZrBLXyWbA7q1vg== + dependencies: + "@storybook/api" "6.4.21" + "@storybook/channels" "6.4.21" + "@storybook/client-logger" "6.4.21" + "@storybook/core-events" "6.4.21" + "@storybook/csf" "0.0.2--canary.87bc651.0" + "@storybook/router" "6.4.21" + "@storybook/theming" "6.4.21" + "@types/webpack-env" "^1.16.0" + core-js "^3.8.2" + global "^4.4.0" + regenerator-runtime "^0.13.7" + "@storybook/api@6.4.20": version "6.4.20" resolved "https://registry.npmjs.org/@storybook/api/-/api-6.4.20.tgz#65da720985b4b46998a405bddc42c9cef9bad7e4" @@ -1434,6 +1451,29 @@ ts-dedent "^2.0.0" util-deprecate "^1.0.2" +"@storybook/api@6.4.21": + version "6.4.21" + resolved "https://registry.npmjs.org/@storybook/api/-/api-6.4.21.tgz#efee41ae7bde37f6fe43ee960fef1a261b1b1dd6" + integrity sha512-AULsLd7ew11IRCpzffyLFGl5cwt9BLMok33DcIlCyvXsiqLm4/OsbgM4sj6QqWVuxcFlWMQJHoRJyeFlULFvZA== + dependencies: + "@storybook/channels" "6.4.21" + "@storybook/client-logger" "6.4.21" + "@storybook/core-events" "6.4.21" + "@storybook/csf" "0.0.2--canary.87bc651.0" + "@storybook/router" "6.4.21" + "@storybook/semver" "^7.3.2" + "@storybook/theming" "6.4.21" + core-js "^3.8.2" + fast-deep-equal "^3.1.3" + global "^4.4.0" + lodash "^4.17.21" + memoizerific "^1.11.3" + regenerator-runtime "^0.13.7" + store2 "^2.12.0" + telejson "^5.3.2" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + "@storybook/builder-webpack4@6.4.20": version "6.4.20" resolved "https://registry.npmjs.org/@storybook/builder-webpack4/-/builder-webpack4-6.4.20.tgz#e3b5d6b665fbf5a1ec75b7ef32c4c811897ef20d" @@ -1542,6 +1582,15 @@ ts-dedent "^2.0.0" util-deprecate "^1.0.2" +"@storybook/channels@6.4.21": + version "6.4.21" + resolved "https://registry.npmjs.org/@storybook/channels/-/channels-6.4.21.tgz#0f1924963f77ec0c3d82aa643a246824ca9f5fca" + integrity sha512-qgy8z3Hp04Q4p+E/8V9MamYYJLW8z1uv1Z+rvosNkg+eAApPg+Qe08BSj59OAUwPLrr2vpBW7WZ/BYSieW1tUg== + dependencies: + core-js "^3.8.2" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + "@storybook/client-api@6.4.20": version "6.4.20" resolved "https://registry.npmjs.org/@storybook/client-api/-/client-api-6.4.20.tgz#17a24af4bc047f7a6de647b9c1844ab4e40baf83" @@ -1576,6 +1625,14 @@ core-js "^3.8.2" global "^4.4.0" +"@storybook/client-logger@6.4.21": + version "6.4.21" + resolved "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-6.4.21.tgz#7df21cec4d5426669e828af59232ec44ea19c81a" + integrity sha512-XkVCQ5swyYDVh5U+87DGRBdC5utJBpVW7kU5P14TQKMnSc/yHbMcXWaA89K8WKDa/WGkGbc0bKi4WrUwHFg2FA== + dependencies: + core-js "^3.8.2" + global "^4.4.0" + "@storybook/components@6.4.20": version "6.4.20" resolved "https://registry.npmjs.org/@storybook/components/-/components-6.4.20.tgz#d063b6a7e70e1be7c8aa79220bb2cd92be8057a1" @@ -1694,6 +1751,13 @@ dependencies: core-js "^3.8.2" +"@storybook/core-events@6.4.21": + version "6.4.21" + resolved "https://registry.npmjs.org/@storybook/core-events/-/core-events-6.4.21.tgz#28fff8b10c0d564259edf4439ff8677615ce59c0" + integrity sha512-K6b9M1zYvW/Kfb1cnH6JDfmFvTYDMx/ot9zdl9O5SPH9glUwzOXSk8qKu6GmZTiW2YnC2nKbjaN20mfMsCBPGw== + dependencies: + core-js "^3.8.2" + "@storybook/core-server@6.4.20": version "6.4.20" resolved "https://registry.npmjs.org/@storybook/core-server/-/core-server-6.4.20.tgz#6bdf6dd5d83713034df950a98f7638e23c64171c" @@ -1915,6 +1979,23 @@ react-router-dom "^6.0.0" ts-dedent "^2.0.0" +"@storybook/router@6.4.21": + version "6.4.21" + resolved "https://registry.npmjs.org/@storybook/router/-/router-6.4.21.tgz#a18172601907918c1442a8a125c9c625d798d09b" + integrity sha512-otn3xYc017SNebeA95xLQ7P6elfyu9541QteXbLR5gFvrT+MB/8zMRZrVuD7n1xwpBgazlonzAdODC736Be9jQ== + dependencies: + "@storybook/client-logger" "6.4.21" + core-js "^3.8.2" + fast-deep-equal "^3.1.3" + global "^4.4.0" + history "5.0.0" + lodash "^4.17.21" + memoizerific "^1.11.3" + qs "^6.10.0" + react-router "^6.0.0" + react-router-dom "^6.0.0" + ts-dedent "^2.0.0" + "@storybook/semver@^7.3.2": version "7.3.2" resolved "https://registry.npmjs.org/@storybook/semver/-/semver-7.3.2.tgz#f3b9c44a1c9a0b933c04e66d0048fcf2fa10dac0" @@ -1978,6 +2059,24 @@ resolve-from "^5.0.0" ts-dedent "^2.0.0" +"@storybook/theming@6.4.21": + version "6.4.21" + resolved "https://registry.npmjs.org/@storybook/theming/-/theming-6.4.21.tgz#ea1a33be70c654cb31e5b38fae93f72171e88ef8" + integrity sha512-7pLNwmqbyqCeHXzjsacI69IdJcAZr6zoZA84iGqx+Na32OI8wtIpFczbwuYpVPN2jzgRYp23CgIv1Gz27yk/zw== + dependencies: + "@emotion/core" "^10.1.1" + "@emotion/is-prop-valid" "^0.8.6" + "@emotion/styled" "^10.0.27" + "@storybook/client-logger" "6.4.21" + core-js "^3.8.2" + deep-object-diff "^1.1.0" + emotion-theming "^10.0.27" + global "^4.4.0" + memoizerific "^1.11.3" + polished "^4.0.5" + resolve-from "^5.0.0" + ts-dedent "^2.0.0" + "@storybook/ui@6.4.20": version "6.4.20" resolved "https://registry.npmjs.org/@storybook/ui/-/ui-6.4.20.tgz#30e8fba0877b66000841046133d3dc098a807d13" From 4b875fd55bdc2e80d89a163e56d778f9e99f1d2b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Apr 2022 04:39:46 +0000 Subject: [PATCH 28/58] build(deps): bump graphiql from 1.8.3 to 1.8.4 Bumps [graphiql](https://github.com/graphql/graphiql) from 1.8.3 to 1.8.4. - [Release notes](https://github.com/graphql/graphiql/releases) - [Changelog](https://github.com/graphql/graphiql/blob/main/CHANGELOG.md) - [Commits](https://github.com/graphql/graphiql/compare/graphiql@1.8.3...graphql-language-service-types@1.8.4) --- updated-dependencies: - dependency-name: graphiql dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- yarn.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/yarn.lock b/yarn.lock index e469f8432b..4919937660 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2296,10 +2296,10 @@ stream-events "^1.0.4" xdg-basedir "^4.0.0" -"@graphiql/toolkit@^0.4.2": - version "0.4.2" - resolved "https://registry.npmjs.org/@graphiql/toolkit/-/toolkit-0.4.2.tgz#34de819add64672f3f7d4830dffb2094fb8d5366" - integrity sha512-14uG67QrONbRrhXwvBJFsMfcQfexmGhj7dgkputesx9xuPUkcCDNmVULnVA8sGYt8P/rSvjkfQYx3rtfW+GhAQ== +"@graphiql/toolkit@^0.4.3": + version "0.4.3" + resolved "https://registry.npmjs.org/@graphiql/toolkit/-/toolkit-0.4.3.tgz#2653d045693d902f7faaf87b9047e8786397ec48" + integrity sha512-L0l6BezvTXmWZhtdmZxirhYwKzcZToAciQY0A13KRAWSpJ9bb/ZdkBpcz3fOXrsjuJHf0wBr6Vk9kztJ6lV7uA== dependencies: "@n1ru4l/push-pull-async-iterable-iterator" "^3.1.0" meros "^1.1.4" @@ -13535,11 +13535,11 @@ grapheme-splitter@^1.0.4: integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== graphiql@^1.5.12: - version "1.8.3" - resolved "https://registry.npmjs.org/graphiql/-/graphiql-1.8.3.tgz#4696755cbba851c93aea9deacbcf4229044a705d" - integrity sha512-3qb3jdlzg8nqQCRMnch6lG11royrE6etP2eoDKLxdrSpdaxI0PgNNttbMAJJYfsqEJ0XHcXtUDt1jH6jkKOK4Q== + version "1.8.4" + resolved "https://registry.npmjs.org/graphiql/-/graphiql-1.8.4.tgz#3a447eae85d839eb207a07fc3aabc6f3a10df46d" + integrity sha512-mEYtfympvlZ4E1VMEMZ0BG3NCLA9L69EEbnpHpAA12oWz3aul4HXWl59JS0aHZftyiPx1/gHjSsjctkhbazT9g== dependencies: - "@graphiql/toolkit" "^0.4.2" + "@graphiql/toolkit" "^0.4.3" codemirror "^5.58.2" codemirror-graphql "^1.2.15" copy-to-clipboard "^3.2.0" From 2fc0e86616246b02aa1f7812633ec294fbe272c5 Mon Sep 17 00:00:00 2001 From: Luna Stadler Date: Fri, 8 Apr 2022 16:30:54 +0200 Subject: [PATCH 29/58] Move refresh handling into KubernetesClustersSupplier implementations Signed-off-by: Luna Stadler --- .changeset/hot-items-smoke.md | 31 +++++++++++-------- docs/features/kubernetes/installation.md | 29 ++++++++++------- plugins/kubernetes-backend/api-report.md | 10 +++--- plugins/kubernetes-backend/package.json | 6 ++-- .../cluster-locator/ConfigClusterLocator.ts | 2 -- .../cluster-locator/GkeClusterLocator.test.ts | 7 +---- .../src/cluster-locator/GkeClusterLocator.ts | 24 ++++++++++++-- .../src/cluster-locator/index.test.ts | 1 - .../src/cluster-locator/index.ts | 20 ++++++------ .../MultiTenantServiceLocator.test.ts | 3 -- .../src/service/KubernetesBuilder.test.ts | 2 -- .../src/service/KubernetesBuilder.ts | 30 ++++++++---------- plugins/kubernetes-backend/src/types/types.ts | 11 ++----- 13 files changed, 93 insertions(+), 83 deletions(-) diff --git a/.changeset/hot-items-smoke.md b/.changeset/hot-items-smoke.md index 52c5088d3e..c9b9c8a135 100644 --- a/.changeset/hot-items-smoke.md +++ b/.changeset/hot-items-smoke.md @@ -10,7 +10,7 @@ the `getClusters` method is now called whenever the list of clusters is needed. Existing `KubernetesClustersSupplier` implementations will need to ensure that `getClusters` can be called frequently and should return a cached result from `getClusters` instead. -For example, here's a simple example of this in `packages/backend/src/plugins/kubernetes.ts`: +For example, here's a simple example of a custom supplier in `packages/backend/src/plugins/kubernetes.ts`: ```diff -import { KubernetesBuilder } from '@backstage/plugin-kubernetes-backend'; @@ -21,9 +21,20 @@ For example, here's a simple example of this in `packages/backend/src/plugins/ku +} from '@backstage/plugin-kubernetes-backend'; import { Router } from 'express'; import { PluginEnvironment } from '../types'; - ++import { Duration } from 'luxon'; ++ +export class CustomClustersSupplier implements KubernetesClustersSupplier { -+ private clusterDetails: ClusterDetails[] = []; ++ constructor(private clusterDetails: ClusterDetails[] = []) {} ++ ++ static create(refreshInterval: Duration) { ++ const clusterSupplier = new CustomClustersSupplier(); ++ // setup refresh, e.g. using a copy of https://github.com/backstage/backstage/blob/master/plugins/search-backend-node/src/runPeriodically.ts ++ runPeriodically( ++ () => clusterSupplier.refreshClusters(), ++ refreshInterval.toMillis(), ++ ); ++ return clusterSupplier; ++ } + + async refreshClusters(): Promise { + this.clusterDetails = []; // fetch from somewhere @@ -33,7 +44,7 @@ For example, here's a simple example of this in `packages/backend/src/plugins/ku + return this.clusterDetails; + } +} -+ + export default async function createPlugin( env: PluginEnvironment, ): Promise { @@ -43,14 +54,8 @@ For example, here's a simple example of this in `packages/backend/src/plugins/ku config: env.config, - }).build(); + }); -+ -+ const clusterSupplier = new CustomClustersSupplier(); -+ builder.setClusterSupplier(clusterSupplier); -+ ++ builder.setClusterSupplier( ++ CustomClustersSupplier.create(Duration.fromObject({ minutes: 60 })), ++ ); + const { router } = await builder.build(); - return router; - } ``` - -If you need to adjust the refresh interval from the default once per hour -you can call `builder.setClusterRefreshInterval`. diff --git a/docs/features/kubernetes/installation.md b/docs/features/kubernetes/installation.md index 4b4ba1139d..e920bd44ea 100644 --- a/docs/features/kubernetes/installation.md +++ b/docs/features/kubernetes/installation.md @@ -108,9 +108,20 @@ Change the following in `packages/backend/src/plugin/kubernetes.ts`: +} from '@backstage/plugin-kubernetes-backend'; import { Router } from 'express'; import { PluginEnvironment } from '../types'; - ++import { Duration } from 'luxon'; ++ +export class CustomClustersSupplier implements KubernetesClustersSupplier { -+ private clusterDetails: ClusterDetails[] = []; ++ constructor(private clusterDetails: ClusterDetails[] = []) {} ++ ++ static create(refreshInterval: Duration) { ++ const clusterSupplier = new CustomClustersSupplier(); ++ // setup refresh, e.g. using a copy of https://github.com/backstage/backstage/blob/master/plugins/search-backend-node/src/runPeriodically.ts ++ runPeriodically( ++ () => clusterSupplier.refreshClusters(), ++ refreshInterval.toMillis(), ++ ); ++ return clusterSupplier; ++ } + + async refreshClusters(): Promise { + this.clusterDetails = []; // fetch from somewhere @@ -120,7 +131,7 @@ Change the following in `packages/backend/src/plugin/kubernetes.ts`: + return this.clusterDetails; + } +} -+ + export default async function createPlugin( env: PluginEnvironment, ): Promise { @@ -130,18 +141,12 @@ Change the following in `packages/backend/src/plugin/kubernetes.ts`: config: env.config, - }).build(); + }); -+ -+ const clusterSupplier = new CustomClustersSupplier(); -+ builder.setClusterSupplier(clusterSupplier); -+ ++ builder.setClusterSupplier( ++ CustomClustersSupplier.create(Duration.fromObject({ minutes: 60 })), ++ ); + const { router } = await builder.build(); - return router; - } ``` -If you need to adjust the refresh interval from the default once per hour -you can call `builder.setClusterRefreshInterval`. - ## Running Backstage locally Start the frontend and the backend app by diff --git a/plugins/kubernetes-backend/api-report.md b/plugins/kubernetes-backend/api-report.md index 573198acf0..691b9443e5 100644 --- a/plugins/kubernetes-backend/api-report.md +++ b/plugins/kubernetes-backend/api-report.md @@ -4,6 +4,7 @@ ```ts import { Config } from '@backstage/config'; +import { Duration } from 'luxon'; import express from 'express'; import type { FetchResponse } from '@backstage/plugin-kubernetes-common'; import type { JsonObject } from '@backstage/types'; @@ -85,7 +86,9 @@ export class KubernetesBuilder { // (undocumented) build(): KubernetesBuilderReturn; // (undocumented) - protected buildClusterSupplier(): KubernetesClustersSupplier; + protected buildClusterSupplier( + refreshInterval: Duration, + ): KubernetesClustersSupplier; // (undocumented) protected buildCustomResources(): CustomResource[]; // (undocumented) @@ -125,10 +128,10 @@ export class KubernetesBuilder { // (undocumented) protected getServiceLocatorMethod(): ServiceLocatorMethod; // (undocumented) - setClusterRefreshInterval(refreshMs: number): this; - // (undocumented) setClusterSupplier(clusterSupplier?: KubernetesClustersSupplier): this; // (undocumented) + setDefaultClusterRefreshInterval(refreshInterval: Duration): this; + // (undocumented) setFetcher(fetcher?: KubernetesFetcher): this; // (undocumented) setObjectsProvider(objectsProvider?: KubernetesObjectsProvider): this; @@ -151,7 +154,6 @@ export type KubernetesBuilderReturn = Promise<{ // @public (undocumented) export interface KubernetesClustersSupplier { getClusters(): Promise; - refreshClusters(): Promise; } // Warning: (ae-missing-release-tag) "KubernetesEnvironment" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) diff --git a/plugins/kubernetes-backend/package.json b/plugins/kubernetes-backend/package.json index a55ec70780..f5eb974431 100644 --- a/plugins/kubernetes-backend/package.json +++ b/plugins/kubernetes-backend/package.json @@ -43,6 +43,7 @@ "@google-cloud/container": "^3.0.0", "@kubernetes/client-node": "^0.16.0", "@types/express": "^4.17.6", + "@types/luxon": "^2.0.4", "aws-sdk": "^2.840.0", "aws4": "^1.11.0", "compression": "^1.7.4", @@ -52,6 +53,7 @@ "fs-extra": "10.0.1", "helmet": "^5.0.2", "lodash": "^4.17.21", + "luxon": "^2.0.2", "morgan": "^1.10.0", "stream-buffers": "^3.0.2", "winston": "^3.2.1", @@ -60,8 +62,8 @@ "devDependencies": { "@backstage/cli": "^0.17.0-next.1", "@types/aws4": "^1.5.1", - "supertest": "^6.1.3", - "aws-sdk-mock": "^5.2.1" + "aws-sdk-mock": "^5.2.1", + "supertest": "^6.1.3" }, "files": [ "dist", diff --git a/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.ts b/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.ts index 893db0f5d0..1bde1226dd 100644 --- a/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.ts +++ b/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.ts @@ -77,8 +77,6 @@ export class ConfigClusterLocator implements KubernetesClustersSupplier { ); } - async refreshClusters(): Promise {} - async getClusters(): Promise { return this.clusterDetails; } diff --git a/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.test.ts b/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.test.ts index 51062066da..6bef8e0009 100644 --- a/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.test.ts +++ b/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.test.ts @@ -69,7 +69,6 @@ describe('GkeClusterLocator', () => { listClusters: mockedListClusters, } as any); - await sut.refreshClusters(); const result = await sut.getClusters(); expect(result).toStrictEqual([]); @@ -101,7 +100,6 @@ describe('GkeClusterLocator', () => { listClusters: mockedListClusters, } as any); - await sut.refreshClusters(); const result = await sut.getClusters(); expect(result).toStrictEqual([ @@ -139,7 +137,6 @@ describe('GkeClusterLocator', () => { listClusters: mockedListClusters, } as any); - await sut.refreshClusters(); const result = await sut.getClusters(); expect(result).toStrictEqual([ @@ -182,7 +179,6 @@ describe('GkeClusterLocator', () => { listClusters: mockedListClusters, } as any); - await sut.refreshClusters(); const result = await sut.getClusters(); expect(result).toStrictEqual([ @@ -221,7 +217,7 @@ describe('GkeClusterLocator', () => { listClusters: mockedListClusters, } as any); - await expect(sut.refreshClusters()).rejects.toThrow( + await expect(sut.getClusters()).rejects.toThrow( 'There was an error retrieving clusters from GKE for projectId=some-project region=some-region; caused by Error: some error', ); @@ -254,7 +250,6 @@ describe('GkeClusterLocator', () => { listClusters: mockedListClusters, } as any); - await sut.refreshClusters(); const result = await sut.getClusters(); expect(result).toStrictEqual([ diff --git a/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.ts b/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.ts index 8484f5006b..0eb25c2acd 100644 --- a/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.ts +++ b/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.ts @@ -17,6 +17,8 @@ import { Config } from '@backstage/config'; import { ForwardedError } from '@backstage/errors'; import * as container from '@google-cloud/container'; +import { Duration } from 'luxon'; +import { runPeriodically } from '../service/runPeriodically'; import { ClusterDetails, GKEClusterDetails, @@ -36,11 +38,13 @@ export class GkeClusterLocator implements KubernetesClustersSupplier { private readonly options: GkeClusterLocatorOptions, private readonly client: container.v1.ClusterManagerClient, private clusterDetails: GKEClusterDetails[] | undefined = undefined, + private hasClusterDetails: boolean = false, ) {} static fromConfigWithClient( config: Config, client: container.v1.ClusterManagerClient, + refreshInterval: Duration | undefined = undefined, ): GkeClusterLocator { const options = { projectId: config.getString('projectId'), @@ -50,17 +54,32 @@ export class GkeClusterLocator implements KubernetesClustersSupplier { config.getOptionalBoolean('skipMetricsLookup') ?? false, exposeDashboard: config.getOptionalBoolean('exposeDashboard') ?? false, }; - return new GkeClusterLocator(options, client); + const gkeClusterLocator = new GkeClusterLocator(options, client); + if (refreshInterval) { + runPeriodically( + () => gkeClusterLocator.refreshClusters(), + refreshInterval.toMillis(), + ); + } + return gkeClusterLocator; } - static fromConfig(config: Config): GkeClusterLocator { + static fromConfig( + config: Config, + refreshInterval: Duration | undefined = undefined, + ): GkeClusterLocator { return GkeClusterLocator.fromConfigWithClient( config, new container.v1.ClusterManagerClient(), + refreshInterval, ); } async getClusters(): Promise { + if (!this.hasClusterDetails) { + // refresh at least once when first called, when retries are disabled and in tests + await this.refreshClusters(); + } return this.clusterDetails ?? []; } @@ -97,6 +116,7 @@ export class GkeClusterLocator implements KubernetesClustersSupplier { } : {}), })); + this.hasClusterDetails = true; } catch (e) { throw new ForwardedError( `There was an error retrieving clusters from GKE for projectId=${projectId} region=${region}`, diff --git a/plugins/kubernetes-backend/src/cluster-locator/index.test.ts b/plugins/kubernetes-backend/src/cluster-locator/index.test.ts index 2bdc37c31c..cc7e7d07d6 100644 --- a/plugins/kubernetes-backend/src/cluster-locator/index.test.ts +++ b/plugins/kubernetes-backend/src/cluster-locator/index.test.ts @@ -46,7 +46,6 @@ describe('getCombinedClusterSupplier', () => { ); const clusterSupplier = getCombinedClusterSupplier(config); - await clusterSupplier.refreshClusters(); const result = await clusterSupplier.getClusters(); expect(result).toStrictEqual([ diff --git a/plugins/kubernetes-backend/src/cluster-locator/index.ts b/plugins/kubernetes-backend/src/cluster-locator/index.ts index fec92d06d7..53aeb44f8b 100644 --- a/plugins/kubernetes-backend/src/cluster-locator/index.ts +++ b/plugins/kubernetes-backend/src/cluster-locator/index.ts @@ -15,18 +15,16 @@ */ import { Config } from '@backstage/config'; +import { Duration } from 'luxon'; import { ClusterDetails, KubernetesClustersSupplier } from '../types/types'; import { ConfigClusterLocator } from './ConfigClusterLocator'; import { GkeClusterLocator } from './GkeClusterLocator'; class CombinedClustersSupplier implements KubernetesClustersSupplier { - constructor( - readonly clusterSuppliers: KubernetesClustersSupplier[], - private clusterDetails: ClusterDetails[] | undefined = undefined, - ) {} + constructor(readonly clusterSuppliers: KubernetesClustersSupplier[]) {} - async refreshClusters(): Promise { - this.clusterDetails = await Promise.all( + async getClusters(): Promise { + return await Promise.all( this.clusterSuppliers.map(supplier => supplier.getClusters()), ) .then(res => { @@ -36,14 +34,11 @@ class CombinedClustersSupplier implements KubernetesClustersSupplier { throw e; }); } - - async getClusters(): Promise { - return this.clusterDetails ?? []; - } } export const getCombinedClusterSupplier = ( rootConfig: Config, + refreshInterval: Duration | undefined = undefined, ): KubernetesClustersSupplier => { const clusterSuppliers = rootConfig .getConfigArray('kubernetes.clusterLocatorMethods') @@ -53,7 +48,10 @@ export const getCombinedClusterSupplier = ( case 'config': return ConfigClusterLocator.fromConfig(clusterLocatorMethod); case 'gke': - return GkeClusterLocator.fromConfig(clusterLocatorMethod); + return GkeClusterLocator.fromConfig( + clusterLocatorMethod, + refreshInterval, + ); default: throw new Error( `Unsupported kubernetes.clusterLocatorMethods: "${type}"`, diff --git a/plugins/kubernetes-backend/src/service-locator/MultiTenantServiceLocator.test.ts b/plugins/kubernetes-backend/src/service-locator/MultiTenantServiceLocator.test.ts index 974f554f45..0dce2305bf 100644 --- a/plugins/kubernetes-backend/src/service-locator/MultiTenantServiceLocator.test.ts +++ b/plugins/kubernetes-backend/src/service-locator/MultiTenantServiceLocator.test.ts @@ -20,7 +20,6 @@ import { MultiTenantServiceLocator } from './MultiTenantServiceLocator'; describe('MultiTenantConfigClusterLocator', () => { it('empty clusters returns empty cluster details', async () => { const sut = new MultiTenantServiceLocator({ - refreshClusters: async () => {}, getClusters: async () => [], }); @@ -31,7 +30,6 @@ describe('MultiTenantConfigClusterLocator', () => { it('one clusters returns one cluster details', async () => { const sut = new MultiTenantServiceLocator({ - refreshClusters: async () => {}, getClusters: async () => { return [ { @@ -58,7 +56,6 @@ describe('MultiTenantConfigClusterLocator', () => { it('two clusters returns two cluster details', async () => { const sut = new MultiTenantServiceLocator({ - refreshClusters: async () => {}, getClusters: async () => { return [ { diff --git a/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts b/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts index c3afa4fb6a..37dad8c3e4 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts @@ -59,7 +59,6 @@ describe('KubernetesBuilder', () => { }, ]; const clusterSupplier: KubernetesClustersSupplier = { - async refreshClusters() {}, async getClusters() { return clusters; }, @@ -180,7 +179,6 @@ describe('KubernetesBuilder', () => { }, ]; const clusterSupplier: KubernetesClustersSupplier = { - async refreshClusters() {}, async getClusters() { return clusters; }, diff --git a/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts b/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts index 9cdef9f00d..a3dfc8b005 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts @@ -17,6 +17,7 @@ import { Config } from '@backstage/config'; import express from 'express'; import Router from 'express-promise-router'; import { Logger } from 'winston'; +import { Duration } from 'luxon'; import { getCombinedClusterSupplier } from '../cluster-locator'; import { MultiTenantServiceLocator } from '../service-locator/MultiTenantServiceLocator'; import { @@ -36,7 +37,6 @@ import { KubernetesFanOutHandler, } from './KubernetesFanOutHandler'; import { KubernetesClientBasedFetcher } from './KubernetesFetcher'; -import { runPeriodically } from './runPeriodically'; export interface KubernetesEnvironment { logger: Logger; @@ -59,7 +59,9 @@ export type KubernetesBuilderReturn = Promise<{ export class KubernetesBuilder { private clusterSupplier?: KubernetesClustersSupplier; - private clusterRefreshMs: number = 60 * 60 * 1000; // defaults to once per hour + private defaultClusterRefreshInterval: Duration = Duration.fromObject({ + minutes: 60, + }); private objectsProvider?: KubernetesObjectsProvider; private fetcher?: KubernetesFetcher; private serviceLocator?: KubernetesServiceLocator; @@ -91,17 +93,9 @@ export class KubernetesBuilder { const fetcher = this.fetcher ?? this.buildFetcher(); - const clusterSupplier = this.clusterSupplier ?? this.buildClusterSupplier(); - - // we cannot use the regular scheduler here because all instances need this info - // and it is not persisted anywhere. - runPeriodically(async () => { - try { - await clusterSupplier.refreshClusters(); - } catch (e) { - logger.warn(`Failed to refresh kubernetes clusters: ${e}`); - } - }, this.clusterRefreshMs); + const clusterSupplier = + this.clusterSupplier ?? + this.buildClusterSupplier(this.defaultClusterRefreshInterval); const serviceLocator = this.serviceLocator ?? @@ -134,8 +128,8 @@ export class KubernetesBuilder { return this; } - public setClusterRefreshInterval(refreshMs: number) { - this.clusterRefreshMs = refreshMs; + public setDefaultClusterRefreshInterval(refreshInterval: Duration) { + this.defaultClusterRefreshInterval = refreshInterval; return this; } @@ -173,9 +167,11 @@ export class KubernetesBuilder { return customResources; } - protected buildClusterSupplier(): KubernetesClustersSupplier { + protected buildClusterSupplier( + refreshInterval: Duration, + ): KubernetesClustersSupplier { const config = this.env.config; - return getCombinedClusterSupplier(config); + return getCombinedClusterSupplier(config, refreshInterval); } protected buildObjectsProvider( diff --git a/plugins/kubernetes-backend/src/types/types.ts b/plugins/kubernetes-backend/src/types/types.ts index 512d916639..2d7e2d3da7 100644 --- a/plugins/kubernetes-backend/src/types/types.ts +++ b/plugins/kubernetes-backend/src/types/types.ts @@ -80,16 +80,11 @@ export type KubernetesObjectTypes = // Used to load cluster details from different sources export interface KubernetesClustersSupplier { - /** - * Refreshes the list of cluster from the source. - * - * This will be called periodically on a schedule to refresh the list - * of clusters. - */ - refreshClusters(): Promise; - /** * Returns the cached list of clusters. + * + * Implementations _should_ cache the clusters and refresh them periodically, + * as getClusters is called whenever the list of clusters is needed. */ getClusters(): Promise; } From c4baa2400946979d04dc9c35ac6eb2e003db0b38 Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Mon, 11 Apr 2022 11:29:56 +0200 Subject: [PATCH 30/58] introduce new search-react package Signed-off-by: Emma Indal --- plugins/search-react/.eslintrc.js | 1 + plugins/search-react/README.md | 1 + plugins/search-react/api-report.md | 64 ++++ plugins/search-react/package.json | 53 ++++ plugins/search-react/src/api.ts | 32 ++ .../src/context/SearchContext.test.tsx | 287 ++++++++++++++++++ .../src/context/SearchContext.tsx | 144 +++++++++ .../SearchContextForStorybook.stories.tsx | 52 ++++ plugins/search-react/src/context/index.tsx | 26 ++ plugins/search-react/src/index.ts | 18 ++ plugins/search-react/src/setupTests.ts | 17 ++ 11 files changed, 695 insertions(+) create mode 100644 plugins/search-react/.eslintrc.js create mode 100644 plugins/search-react/README.md create mode 100644 plugins/search-react/api-report.md create mode 100644 plugins/search-react/package.json create mode 100644 plugins/search-react/src/api.ts create mode 100644 plugins/search-react/src/context/SearchContext.test.tsx create mode 100644 plugins/search-react/src/context/SearchContext.tsx create mode 100644 plugins/search-react/src/context/SearchContextForStorybook.stories.tsx create mode 100644 plugins/search-react/src/context/index.tsx create mode 100644 plugins/search-react/src/index.ts create mode 100644 plugins/search-react/src/setupTests.ts diff --git a/plugins/search-react/.eslintrc.js b/plugins/search-react/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/search-react/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/search-react/README.md b/plugins/search-react/README.md new file mode 100644 index 0000000000..9683a4a5f7 --- /dev/null +++ b/plugins/search-react/README.md @@ -0,0 +1 @@ +# search react diff --git a/plugins/search-react/api-report.md b/plugins/search-react/api-report.md new file mode 100644 index 0000000000..ee8c7b1224 --- /dev/null +++ b/plugins/search-react/api-report.md @@ -0,0 +1,64 @@ +## API Report File for "@backstage/plugin-search-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/useAsync'; +import { ComponentProps } from 'react'; +import { JsonObject } from '@backstage/types'; +import { PropsWithChildren } from 'react'; +import { default as React_2 } from 'react'; +import { SearchQuery } from '@backstage/plugin-search-common'; +import { SearchResultSet } from '@backstage/plugin-search-common'; + +// @public (undocumented) +export interface SearchApi { + // (undocumented) + query(query: SearchQuery): Promise; +} + +// Warning: (ae-forgotten-export) The symbol "QueryResultProps" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "SearchApiProvider" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function SearchApiProviderForStorybook( + props: PropsWithChildren, +): JSX.Element; + +// @public (undocumented) +export const searchApiRef: ApiRef; + +// Warning: (ae-forgotten-export) The symbol "SearchContextValue" needs to be exported by the entry point index.d.ts +// +// @public (undocumented) +export const SearchContext: React_2.Context; + +// @public (undocumented) +export const SearchContextProvider: ({ + initialState, + children, +}: React_2.PropsWithChildren<{ + initialState?: SearchContextState | undefined; +}>) => JSX.Element; + +// Warning: (ae-missing-release-tag) "SearchContextProvider" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export const SearchContextProviderForStorybook: ( + props: ComponentProps & QueryResultProps, +) => JSX.Element; + +// @public +export type SearchContextState = { + term: string; + types: string[]; + filters: JsonObject; + pageCursor?: string; +}; + +// @public (undocumented) +export const useSearch: () => SearchContextValue; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/search-react/package.json b/plugins/search-react/package.json new file mode 100644 index 0000000000..66b6bdfa46 --- /dev/null +++ b/plugins/search-react/package.json @@ -0,0 +1,53 @@ +{ + "name": "@backstage/plugin-search-react", + "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" + }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/search-react" + }, + "keywords": [ + "backstage" + ], + "scripts": { + "build": "backstage-cli package build", + "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", + "start": "backstage-cli package start" + }, + "dependencies": { + "@backstage/plugin-search-common": "^0.3.2", + "@backstage/core-plugin-api": "^1.0.0", + "@backstage/core-app-api": "^1.0.1-next.0", + "react-use": "^17.3.2", + "@backstage/types": "^1.0.0" + }, + "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0", + "react": "^16.13.1 || ^17.0.0" + }, + "devDependencies": { + "@backstage/test-utils": "^1.0.0", + "@testing-library/react": "^13.0.0", + "@testing-library/react-hooks": "^8.0.0", + "@testing-library/jest-dom": "^5.16.4" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/search-react/src/api.ts b/plugins/search-react/src/api.ts new file mode 100644 index 0000000000..eb8c9c23db --- /dev/null +++ b/plugins/search-react/src/api.ts @@ -0,0 +1,32 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { SearchQuery, SearchResultSet } from '@backstage/plugin-search-common'; +import { createApiRef } from '@backstage/core-plugin-api'; + +/** + * @public + */ +export const searchApiRef = createApiRef({ + id: 'plugin.search.queryservice', +}); + +/** + * @public + */ +export interface SearchApi { + query(query: SearchQuery): Promise; +} diff --git a/plugins/search-react/src/context/SearchContext.test.tsx b/plugins/search-react/src/context/SearchContext.test.tsx new file mode 100644 index 0000000000..b19953f6a5 --- /dev/null +++ b/plugins/search-react/src/context/SearchContext.test.tsx @@ -0,0 +1,287 @@ +/* + * 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 { useApi } from '@backstage/core-plugin-api'; +import { render, screen, waitFor } from '@testing-library/react'; +import { act, renderHook } from '@testing-library/react-hooks'; +import React from 'react'; +import { SearchContextProvider, useSearch } from './SearchContext'; + +jest.mock('@backstage/core-plugin-api', () => ({ + ...jest.requireActual('@backstage/core-plugin-api'), + useApi: jest.fn(), +})); + +describe('SearchContext', () => { + const query = jest.fn(); + + const wrapper = ({ children, initialState }: any) => ( + + {children} + + ); + + const initialState = { + term: '', + filters: {}, + types: ['*'], + }; + + beforeEach(() => { + query.mockResolvedValue({}); + (useApi as jest.Mock).mockReturnValue({ query: query }); + }); + + afterAll(() => { + jest.resetAllMocks(); + }); + + it('Passes children', async () => { + const text = 'text'; + + render( + + {text} + , + ); + + await waitFor(() => { + expect(screen.getByText(text)).toBeInTheDocument(); + }); + }); + + it('Throws error when no context is set', () => { + const { result } = renderHook(() => useSearch()); + + expect(result.error).toEqual( + Error('useSearch must be used within a SearchContextProvider'), + ); + }); + + it('Uses initial state values', async () => { + const { result, waitForNextUpdate } = renderHook(() => useSearch(), { + wrapper, + initialProps: { + initialState, + }, + }); + + await waitForNextUpdate(); + + expect(result.current).toEqual(expect.objectContaining(initialState)); + }); + + it('Resets cursor when term is set (and different from previous)', async () => { + const { result, waitForNextUpdate } = renderHook(() => useSearch(), { + wrapper, + initialProps: { + initialState: { + ...initialState, + pageCursor: 'SOMEPAGE', + }, + }, + }); + + await waitForNextUpdate(); + + expect(result.current.pageCursor).toEqual('SOMEPAGE'); + + act(() => { + result.current.setTerm('first term'); + }); + + act(() => { + result.current.setPageCursor('OTHERPAGE'); + }); + + await waitForNextUpdate(); + + expect(result.current.pageCursor).toEqual('OTHERPAGE'); + + act(() => { + result.current.setTerm('second term'); + }); + + await waitForNextUpdate(); + + expect(result.current.pageCursor).toEqual(undefined); + }); + + describe('Performs search (and sets results)', () => { + it('When term is set', async () => { + const { result, waitForNextUpdate } = renderHook(() => useSearch(), { + wrapper, + initialProps: { + initialState, + }, + }); + + await waitForNextUpdate(); + + const term = 'term'; + + act(() => { + result.current.setTerm(term); + }); + + await waitForNextUpdate(); + + expect(query).toHaveBeenLastCalledWith({ + filters: {}, + types: ['*'], + term, + }); + }); + + it('When filters are set', async () => { + const { result, waitForNextUpdate } = renderHook(() => useSearch(), { + wrapper, + initialProps: { + initialState, + }, + }); + + await waitForNextUpdate(); + + const filters = { filter: 'filter' }; + + act(() => { + result.current.setFilters(filters); + }); + + await waitForNextUpdate(); + + expect(query).toHaveBeenLastCalledWith({ + filters, + types: ['*'], + term: '', + }); + }); + + it('When page is set', async () => { + const { result, waitForNextUpdate } = renderHook(() => useSearch(), { + wrapper, + initialProps: { + initialState, + }, + }); + + await waitForNextUpdate(); + + act(() => { + result.current.setPageCursor('SOMEPAGE'); + }); + + await waitForNextUpdate(); + + expect(query).toHaveBeenLastCalledWith({ + filters: {}, + types: ['*'], + pageCursor: 'SOMEPAGE', + term: '', + }); + }); + + it('When types is set', async () => { + const { result, waitForNextUpdate } = renderHook(() => useSearch(), { + wrapper, + initialProps: { + initialState, + }, + }); + + await waitForNextUpdate(); + + const types = ['type']; + + act(() => { + result.current.setTypes(types); + }); + + await waitForNextUpdate(); + + expect(query).toHaveBeenLastCalledWith({ + types, + filters: {}, + term: '', + }); + }); + + it('provides function for fetch the next page', async () => { + query.mockResolvedValue({ + results: [], + nextPageCursor: 'NEXT', + }); + + const { result, waitForNextUpdate } = renderHook(() => useSearch(), { + wrapper, + initialProps: { + initialState, + }, + }); + + await waitForNextUpdate(); + + expect(result.current.fetchNextPage).toBeDefined(); + expect(result.current.fetchPreviousPage).toBeUndefined(); + + act(() => { + result.current.fetchNextPage!(); + }); + + await waitForNextUpdate(); + + expect(query).toHaveBeenLastCalledWith({ + types: ['*'], + filters: {}, + term: '', + pageCursor: 'NEXT', + }); + }); + + it('provides function for fetch the previous page', async () => { + query.mockResolvedValue({ + results: [], + previousPageCursor: 'PREVIOUS', + }); + + const { result, waitForNextUpdate } = renderHook(() => useSearch(), { + wrapper, + initialProps: { + initialState, + }, + }); + + await waitForNextUpdate(); + + expect(result.current.fetchNextPage).toBeUndefined(); + expect(result.current.fetchPreviousPage).toBeDefined(); + + act(() => { + result.current.fetchPreviousPage!(); + }); + + await waitForNextUpdate(); + + expect(query).toHaveBeenLastCalledWith({ + types: ['*'], + filters: {}, + term: '', + pageCursor: 'PREVIOUS', + }); + }); + }); +}); diff --git a/plugins/search-react/src/context/SearchContext.tsx b/plugins/search-react/src/context/SearchContext.tsx new file mode 100644 index 0000000000..217c94cca2 --- /dev/null +++ b/plugins/search-react/src/context/SearchContext.tsx @@ -0,0 +1,144 @@ +/* + * 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 { JsonObject } from '@backstage/types'; +import { useApi, AnalyticsContext } from '@backstage/core-plugin-api'; +import { SearchResultSet } from '@backstage/plugin-search-common'; +import React, { + createContext, + PropsWithChildren, + useCallback, + useContext, + useEffect, + useState, +} from 'react'; +import useAsync, { AsyncState } from 'react-use/lib/useAsync'; +import usePrevious from 'react-use/lib/usePrevious'; +import { searchApiRef } from '../api'; + +type SearchContextValue = { + result: AsyncState; + setTerm: React.Dispatch>; + setTypes: React.Dispatch>; + setFilters: React.Dispatch>; + setPageCursor: React.Dispatch>; + fetchNextPage?: React.DispatchWithoutAction; + fetchPreviousPage?: React.DispatchWithoutAction; +} & SearchContextState; + +/** + * The initial state of `SearchContextProvider`. + * + * @public + */ +export type SearchContextState = { + term: string; + types: string[]; + filters: JsonObject; + pageCursor?: string; +}; + +/** + * @public + */ +export const SearchContext = createContext( + undefined, +); + +const searchInitialState: SearchContextState = { + term: '', + pageCursor: undefined, + filters: {}, + types: [], +}; + +/** + * @public + */ +export const SearchContextProvider = ({ + initialState = searchInitialState, + children, +}: PropsWithChildren<{ initialState?: SearchContextState }>) => { + const searchApi = useApi(searchApiRef); + const [pageCursor, setPageCursor] = useState( + initialState.pageCursor, + ); + const [filters, setFilters] = useState(initialState.filters); + const [term, setTerm] = useState(initialState.term); + const [types, setTypes] = useState(initialState.types); + + const prevTerm = usePrevious(term); + + const result = useAsync( + () => + searchApi.query({ + term, + filters, + pageCursor, + types, + }), + [term, filters, types, pageCursor], + ); + + const hasNextPage = + !result.loading && !result.error && result.value?.nextPageCursor; + const hasPreviousPage = + !result.loading && !result.error && result.value?.previousPageCursor; + const fetchNextPage = useCallback(() => { + setPageCursor(result.value?.nextPageCursor); + }, [result.value?.nextPageCursor]); + const fetchPreviousPage = useCallback(() => { + setPageCursor(result.value?.previousPageCursor); + }, [result.value?.previousPageCursor]); + + useEffect(() => { + // Any time a term is reset, we want to start from page 0. + if (term && prevTerm && term !== prevTerm) { + setPageCursor(undefined); + } + }, [term, prevTerm, initialState.pageCursor]); + + const value: SearchContextValue = { + result, + filters, + setFilters, + term, + setTerm, + types, + setTypes, + pageCursor, + setPageCursor, + fetchNextPage: hasNextPage ? fetchNextPage : undefined, + fetchPreviousPage: hasPreviousPage ? fetchPreviousPage : undefined, + }; + + return ( + + + + ); +}; + +/** + * @public + */ +export const useSearch = () => { + const context = useContext(SearchContext); + if (context === undefined) { + throw new Error('useSearch must be used within a SearchContextProvider'); + } + return context; +}; diff --git a/plugins/search-react/src/context/SearchContextForStorybook.stories.tsx b/plugins/search-react/src/context/SearchContextForStorybook.stories.tsx new file mode 100644 index 0000000000..51297c965f --- /dev/null +++ b/plugins/search-react/src/context/SearchContextForStorybook.stories.tsx @@ -0,0 +1,52 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { ApiProvider } from '@backstage/core-app-api'; +import { SearchResultSet } from '@backstage/plugin-search-common'; +import { TestApiRegistry } from '@backstage/test-utils'; +import React, { ComponentProps, PropsWithChildren } from 'react'; +import { searchApiRef } from '../api'; +import { SearchContextProvider as RealSearchContextProvider } from './SearchContext'; + +type QueryResultProps = { + mockedResults?: SearchResultSet; +}; + +/** + * Utility context provider only for use in Storybook stories. You should use + * the real `` exported by `@backstage/plugin-search-react` in + * your app instead of this! In some cases (like the search page) it may + * already be provided on your behalf. + */ +export const SearchContextProvider = ( + props: ComponentProps & QueryResultProps, +) => { + return ( + + + + ); +}; + +/** + * Utility api provider only for use in Storybook stories. + * + */ +export function SearchApiProvider(props: PropsWithChildren) { + const { mockedResults, children } = props; + const query: any = () => Promise.resolve(mockedResults || {}); + const apiRegistry = TestApiRegistry.from([searchApiRef, { query }]); + return ; +} diff --git a/plugins/search-react/src/context/index.tsx b/plugins/search-react/src/context/index.tsx new file mode 100644 index 0000000000..f2ea486e9d --- /dev/null +++ b/plugins/search-react/src/context/index.tsx @@ -0,0 +1,26 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { + SearchContextProvider, + SearchContext, + useSearch, +} from './SearchContext'; +export type { SearchContextState } from './SearchContext'; +export { + SearchContextProvider as SearchContextProviderForStorybook, + SearchApiProvider as SearchApiProviderForStorybook, +} from './SearchContextForStorybook.stories'; diff --git a/plugins/search-react/src/index.ts b/plugins/search-react/src/index.ts new file mode 100644 index 0000000000..498e4d6ce3 --- /dev/null +++ b/plugins/search-react/src/index.ts @@ -0,0 +1,18 @@ +/* + * 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 * from './api'; +export * from './context'; diff --git a/plugins/search-react/src/setupTests.ts b/plugins/search-react/src/setupTests.ts new file mode 100644 index 0000000000..992b60d3a4 --- /dev/null +++ b/plugins/search-react/src/setupTests.ts @@ -0,0 +1,17 @@ +/* + * 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 '@testing-library/jest-dom'; From bc31ff1bbd192a5d21b7b02f63d82536cbb636ca Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Mon, 11 Apr 2022 11:38:19 +0200 Subject: [PATCH 31/58] move home default template story to the app Signed-off-by: Emma Indal --- .../home}/templates/DefaultTemplate.stories.tsx | 12 ++++-------- .../home}/templates/TemplateBackstageLogo.tsx | 0 .../home}/templates/TemplateBackstageLogoIcon.tsx | 0 .../app/src/components/home}/templates/index.ts | 0 storybook/.storybook/main.js | 1 + 5 files changed, 5 insertions(+), 8 deletions(-) rename {plugins/home/src => packages/app/src/components/home}/templates/DefaultTemplate.stories.tsx (95%) rename {plugins/home/src => packages/app/src/components/home}/templates/TemplateBackstageLogo.tsx (100%) rename {plugins/home/src => packages/app/src/components/home}/templates/TemplateBackstageLogoIcon.tsx (100%) rename {plugins/home/src => packages/app/src/components/home}/templates/index.ts (100%) diff --git a/plugins/home/src/templates/DefaultTemplate.stories.tsx b/packages/app/src/components/home/templates/DefaultTemplate.stories.tsx similarity index 95% rename from plugins/home/src/templates/DefaultTemplate.stories.tsx rename to packages/app/src/components/home/templates/DefaultTemplate.stories.tsx index e2e570dcf6..b2f6034709 100644 --- a/plugins/home/src/templates/DefaultTemplate.stories.tsx +++ b/packages/app/src/components/home/templates/DefaultTemplate.stories.tsx @@ -20,8 +20,8 @@ import { HomePageToolkit, HomePageCompanyLogo, HomePageStarredEntities, -} from '../plugin'; -import { wrapInTestApp, TestApiProvider} from '@backstage/test-utils'; +} from '@backstage/plugin-home'; +import { wrapInTestApp, TestApiProvider } from '@backstage/test-utils'; import { Content, Page, InfoCard } from '@backstage/core-components'; import { starredEntitiesApiRef, @@ -32,10 +32,9 @@ import { configApiRef } from '@backstage/core-plugin-api'; import { ConfigReader } from '@backstage/config'; import { HomePageSearchBar, - SearchContextProvider, - searchApiRef, searchPlugin, } from '@backstage/plugin-search'; +import { searchApiRef, SearchContextProvider } from '@backstage/plugin-search-react'; import { HomePageStackOverflowQuestions } from '@backstage/plugin-stack-overflow'; import { Grid, makeStyles } from '@material-ui/core'; import React, { ComponentType } from 'react'; @@ -54,10 +53,7 @@ export default { <> Promise.resolve({ results: [] }) }], [ configApiRef, diff --git a/plugins/home/src/templates/TemplateBackstageLogo.tsx b/packages/app/src/components/home/templates/TemplateBackstageLogo.tsx similarity index 100% rename from plugins/home/src/templates/TemplateBackstageLogo.tsx rename to packages/app/src/components/home/templates/TemplateBackstageLogo.tsx diff --git a/plugins/home/src/templates/TemplateBackstageLogoIcon.tsx b/packages/app/src/components/home/templates/TemplateBackstageLogoIcon.tsx similarity index 100% rename from plugins/home/src/templates/TemplateBackstageLogoIcon.tsx rename to packages/app/src/components/home/templates/TemplateBackstageLogoIcon.tsx diff --git a/plugins/home/src/templates/index.ts b/packages/app/src/components/home/templates/index.ts similarity index 100% rename from plugins/home/src/templates/index.ts rename to packages/app/src/components/home/templates/index.ts diff --git a/storybook/.storybook/main.js b/storybook/.storybook/main.js index 2356e4e41b..8ed4949cf3 100644 --- a/storybook/.storybook/main.js +++ b/storybook/.storybook/main.js @@ -6,6 +6,7 @@ const WebpackPluginFailBuildOnWarning = require('./webpack-plugin-fail-build-on- */ const BACKSTAGE_CORE_STORIES = [ 'packages/core-components', + 'packages/app', 'plugins/org', 'plugins/search', 'plugins/home', From 09cba0bdaee0b077befe8e46790740298c6fae6a Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Mon, 11 Apr 2022 11:41:59 +0200 Subject: [PATCH 32/58] deprecate search api ref, search api interface and search context in plugin-search Signed-off-by: Emma Indal --- plugins/search/src/apis.ts | 7 + .../SearchContext/SearchContext.test.tsx | 287 ------------------ .../SearchContext/SearchContext.tsx | 9 + .../SearchContextForStorybook.stories.tsx | 48 --- 4 files changed, 16 insertions(+), 335 deletions(-) delete mode 100644 plugins/search/src/components/SearchContext/SearchContext.test.tsx delete mode 100644 plugins/search/src/components/SearchContext/SearchContextForStorybook.stories.tsx diff --git a/plugins/search/src/apis.ts b/plugins/search/src/apis.ts index 908942d87d..62f65dbe4a 100644 --- a/plugins/search/src/apis.ts +++ b/plugins/search/src/apis.ts @@ -21,12 +21,19 @@ import { } from '@backstage/core-plugin-api'; import { ResponseError } from '@backstage/errors'; import { SearchQuery, SearchResultSet } from '@backstage/plugin-search-common'; + import qs from 'qs'; +/** + * @deprecated import from "@backstage/plugin-search-react" instead + */ export const searchApiRef = createApiRef({ id: 'plugin.search.queryservice', }); +/** + * @deprecated import from "@backstage/plugin-search-react" instead + */ export interface SearchApi { query(query: SearchQuery): Promise; } diff --git a/plugins/search/src/components/SearchContext/SearchContext.test.tsx b/plugins/search/src/components/SearchContext/SearchContext.test.tsx deleted file mode 100644 index 6513dc21bb..0000000000 --- a/plugins/search/src/components/SearchContext/SearchContext.test.tsx +++ /dev/null @@ -1,287 +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 { useApi } from '@backstage/core-plugin-api'; -import { render, screen, waitFor } from '@testing-library/react'; -import { act, renderHook } from '@testing-library/react-hooks'; -import React from 'react'; -import { SearchContextProvider, useSearch } from './SearchContext'; - -jest.mock('@backstage/core-plugin-api', () => ({ - ...jest.requireActual('@backstage/core-plugin-api'), - useApi: jest.fn(), -})); - -describe('SearchContext', () => { - const query = jest.fn(); - - const wrapper = ({ children, initialState }: any) => ( - - {children} - - ); - - const initialState = { - term: '', - filters: {}, - types: ['*'], - }; - - beforeEach(() => { - query.mockResolvedValue({}); - (useApi as jest.Mock).mockReturnValue({ query: query }); - }); - - afterAll(() => { - jest.resetAllMocks(); - }); - - it('Passes children', async () => { - const text = 'text'; - - render( - - {text} - , - ); - - await waitFor(() => { - expect(screen.getByText(text)).toBeInTheDocument(); - }); - }); - - it('Throws error when no context is set', () => { - const { result } = renderHook(() => useSearch()); - - expect(result.error).toEqual( - Error('useSearch must be used within a SearchContextProvider'), - ); - }); - - it('Uses initial state values', async () => { - const { result, waitForNextUpdate } = renderHook(() => useSearch(), { - wrapper, - initialProps: { - initialState, - }, - }); - - await waitForNextUpdate(); - - expect(result.current).toEqual(expect.objectContaining(initialState)); - }); - - it('Resets cursor when term is set (and different from previous)', async () => { - const { result, waitForNextUpdate } = renderHook(() => useSearch(), { - wrapper, - initialProps: { - initialState: { - ...initialState, - pageCursor: 'SOMEPAGE', - }, - }, - }); - - await waitForNextUpdate(); - - expect(result.current.pageCursor).toEqual('SOMEPAGE'); - - act(() => { - result.current.setTerm('first term'); - }); - - act(() => { - result.current.setPageCursor('OTHERPAGE'); - }); - - await waitForNextUpdate(); - - expect(result.current.pageCursor).toEqual('OTHERPAGE'); - - act(() => { - result.current.setTerm('second term'); - }); - - await waitForNextUpdate(); - - expect(result.current.pageCursor).toEqual(undefined); - }); - - describe('Performs search (and sets results)', () => { - it('When term is set', async () => { - const { result, waitForNextUpdate } = renderHook(() => useSearch(), { - wrapper, - initialProps: { - initialState, - }, - }); - - await waitForNextUpdate(); - - const term = 'term'; - - act(() => { - result.current.setTerm(term); - }); - - await waitForNextUpdate(); - - expect(query).toHaveBeenLastCalledWith({ - filters: {}, - types: ['*'], - term, - }); - }); - - it('When filters are set', async () => { - const { result, waitForNextUpdate } = renderHook(() => useSearch(), { - wrapper, - initialProps: { - initialState, - }, - }); - - await waitForNextUpdate(); - - const filters = { filter: 'filter' }; - - act(() => { - result.current.setFilters(filters); - }); - - await waitForNextUpdate(); - - expect(query).toHaveBeenLastCalledWith({ - filters, - types: ['*'], - term: '', - }); - }); - - it('When page is set', async () => { - const { result, waitForNextUpdate } = renderHook(() => useSearch(), { - wrapper, - initialProps: { - initialState, - }, - }); - - await waitForNextUpdate(); - - act(() => { - result.current.setPageCursor('SOMEPAGE'); - }); - - await waitForNextUpdate(); - - expect(query).toHaveBeenLastCalledWith({ - filters: {}, - types: ['*'], - pageCursor: 'SOMEPAGE', - term: '', - }); - }); - - it('When types is set', async () => { - const { result, waitForNextUpdate } = renderHook(() => useSearch(), { - wrapper, - initialProps: { - initialState, - }, - }); - - await waitForNextUpdate(); - - const types = ['type']; - - act(() => { - result.current.setTypes(types); - }); - - await waitForNextUpdate(); - - expect(query).toHaveBeenLastCalledWith({ - types, - filters: {}, - term: '', - }); - }); - - it('provides function for fetch the next page', async () => { - query.mockResolvedValue({ - results: [], - nextPageCursor: 'NEXT', - }); - - const { result, waitForNextUpdate } = renderHook(() => useSearch(), { - wrapper, - initialProps: { - initialState, - }, - }); - - await waitForNextUpdate(); - - expect(result.current.fetchNextPage).toBeDefined(); - expect(result.current.fetchPreviousPage).toBeUndefined(); - - act(() => { - result.current.fetchNextPage!(); - }); - - await waitForNextUpdate(); - - expect(query).toHaveBeenLastCalledWith({ - types: ['*'], - filters: {}, - term: '', - pageCursor: 'NEXT', - }); - }); - - it('provides function for fetch the previous page', async () => { - query.mockResolvedValue({ - results: [], - previousPageCursor: 'PREVIOUS', - }); - - const { result, waitForNextUpdate } = renderHook(() => useSearch(), { - wrapper, - initialProps: { - initialState, - }, - }); - - await waitForNextUpdate(); - - expect(result.current.fetchNextPage).toBeUndefined(); - expect(result.current.fetchPreviousPage).toBeDefined(); - - act(() => { - result.current.fetchPreviousPage!(); - }); - - await waitForNextUpdate(); - - expect(query).toHaveBeenLastCalledWith({ - types: ['*'], - filters: {}, - term: '', - pageCursor: 'PREVIOUS', - }); - }); - }); -}); diff --git a/plugins/search/src/components/SearchContext/SearchContext.tsx b/plugins/search/src/components/SearchContext/SearchContext.tsx index 100d8a3ac3..d52e43af88 100644 --- a/plugins/search/src/components/SearchContext/SearchContext.tsx +++ b/plugins/search/src/components/SearchContext/SearchContext.tsx @@ -51,6 +51,9 @@ export type SearchContextState = { pageCursor?: string; }; +/** + * @deprecated import from "@backstage/plugin-search-react" instead + */ export const SearchContext = createContext( undefined, ); @@ -62,6 +65,9 @@ const searchInitialState: SearchContextState = { types: [], }; +/** + * @deprecated import from "@backstage/plugin-search-react" instead + */ export const SearchContextProvider = ({ initialState = searchInitialState, children, @@ -126,6 +132,9 @@ export const SearchContextProvider = ({ ); }; +/** + * @deprecated import from "@backstage/plugin-search-react" instead + */ export const useSearch = () => { const context = useContext(SearchContext); if (context === undefined) { diff --git a/plugins/search/src/components/SearchContext/SearchContextForStorybook.stories.tsx b/plugins/search/src/components/SearchContext/SearchContextForStorybook.stories.tsx deleted file mode 100644 index 7d6c35b00c..0000000000 --- a/plugins/search/src/components/SearchContext/SearchContextForStorybook.stories.tsx +++ /dev/null @@ -1,48 +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 { ApiProvider } from '@backstage/core-app-api'; -import { SearchResultSet } from '@backstage/plugin-search-common'; -import { TestApiRegistry } from '@backstage/test-utils'; -import React, { ComponentProps, PropsWithChildren } from 'react'; -import { searchApiRef } from '../../apis'; -import { SearchContextProvider as RealSearchContextProvider } from './SearchContext'; - -type QueryResultProps = { - mockedResults?: SearchResultSet; -}; - -/** - * Utility context provider only for use in Storybook stories. You should use - * the real `` exported by `@backstage/plugin-search` in - * your app instead of this! In some cases (like the search page) it may - * already be provided on your behalf. - */ -export const SearchContextProvider = ( - props: ComponentProps & QueryResultProps, -) => { - return ( - - - - ); -}; - -export function SearchApiProvider(props: PropsWithChildren) { - const { mockedResults, children } = props; - const query: any = () => Promise.resolve(mockedResults || {}); - const apiRegistry = TestApiRegistry.from([searchApiRef, { query }]); - return ; -} From 301b4606e3823665e1b60b9cbc9ac1ab488f5954 Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Mon, 11 Apr 2022 11:42:57 +0200 Subject: [PATCH 33/58] import from new search-react package Signed-off-by: Emma Indal --- plugins/home/package.json | 2 +- plugins/search/package.json | 1 + .../SearchBar/SearchBar.stories.tsx | 6 +- .../SearchFilter/SearchFilter.stories.tsx | 6 +- .../SearchModal/SearchModal.stories.tsx | 6 +- .../SearchResult/SearchResult.stories.tsx | 7 +- .../SearchType/SearchType.stories.tsx | 6 +- plugins/techdocs/package.json | 2 +- .../src/reader/components/Reader.test.tsx | 2 +- .../components/TechDocsReaderPage.test.tsx | 2 +- .../search/components/TechDocsSearch.test.tsx | 2 +- .../src/search/components/TechDocsSearch.tsx | 5 +- yarn.lock | 99 +++++++++++++++++++ 13 files changed, 125 insertions(+), 21 deletions(-) diff --git a/plugins/home/package.json b/plugins/home/package.json index 43b474704a..e59e7a39bb 100644 --- a/plugins/home/package.json +++ b/plugins/home/package.json @@ -38,7 +38,7 @@ "@backstage/core-components": "^0.9.3-next.1", "@backstage/core-plugin-api": "^1.0.0", "@backstage/plugin-catalog-react": "^1.0.1-next.2", - "@backstage/plugin-search": "^0.7.5-next.0", + "@backstage/plugin-search-react": "^0.0.0", "@backstage/plugin-stack-overflow": "^0.1.0-next.0", "@backstage/theme": "^0.2.15", "@backstage/config": "^1.0.0", diff --git a/plugins/search/package.json b/plugins/search/package.json index c32e830950..4ac891775e 100644 --- a/plugins/search/package.json +++ b/plugins/search/package.json @@ -39,6 +39,7 @@ "@backstage/core-plugin-api": "^1.0.0", "@backstage/errors": "^1.0.0", "@backstage/plugin-catalog-react": "^1.0.1-next.1", + "@backstage/plugin-search-react": "^0.0.0", "@backstage/plugin-search-common": "^0.3.3-next.1", "@backstage/theme": "^0.2.15", "@backstage/types": "^1.0.0", diff --git a/plugins/search/src/components/SearchBar/SearchBar.stories.tsx b/plugins/search/src/components/SearchBar/SearchBar.stories.tsx index c0d4b07965..72c7deb06b 100644 --- a/plugins/search/src/components/SearchBar/SearchBar.stories.tsx +++ b/plugins/search/src/components/SearchBar/SearchBar.stories.tsx @@ -16,7 +16,7 @@ import { Grid, makeStyles, Paper } from '@material-ui/core'; import React, { ComponentType } from 'react'; -import { SearchContextProvider } from '../SearchContext/SearchContextForStorybook.stories'; +import { SearchContextProviderForStorybook } from '@backstage/plugin-search-react'; import { SearchBar } from './SearchBar'; export default { @@ -24,13 +24,13 @@ export default { component: SearchBar, decorators: [ (Story: ComponentType<{}>) => ( - + - + ), ], }; diff --git a/plugins/search/src/components/SearchFilter/SearchFilter.stories.tsx b/plugins/search/src/components/SearchFilter/SearchFilter.stories.tsx index c43753e8d2..3c49b76699 100644 --- a/plugins/search/src/components/SearchFilter/SearchFilter.stories.tsx +++ b/plugins/search/src/components/SearchFilter/SearchFilter.stories.tsx @@ -16,7 +16,7 @@ import { Grid, Paper } from '@material-ui/core'; import React, { ComponentType } from 'react'; -import { SearchContextProvider } from '../SearchContext/SearchContextForStorybook.stories'; +import { SearchContextProviderForStorybook } from '@backstage/plugin-search-react'; import { SearchFilter } from './SearchFilter'; export default { @@ -24,13 +24,13 @@ export default { component: SearchFilter, decorators: [ (Story: ComponentType<{}>) => ( - + - + ), ], }; diff --git a/plugins/search/src/components/SearchModal/SearchModal.stories.tsx b/plugins/search/src/components/SearchModal/SearchModal.stories.tsx index aa0ad0479a..a1d9517674 100644 --- a/plugins/search/src/components/SearchModal/SearchModal.stories.tsx +++ b/plugins/search/src/components/SearchModal/SearchModal.stories.tsx @@ -18,7 +18,7 @@ import { wrapInTestApp } from '@backstage/test-utils'; import { Button } from '@material-ui/core'; import React, { ComponentType } from 'react'; import { rootRouteRef } from '../../plugin'; -import { SearchApiProvider } from '../SearchContext/SearchContextForStorybook.stories'; +import { SearchApiProviderForStorybook } from '@backstage/plugin-search-react'; import { SearchModal } from './SearchModal'; import { useSearchModal } from './useSearchModal'; @@ -57,9 +57,9 @@ export default { decorators: [ (Story: ComponentType<{}>) => wrapInTestApp( - + - , + , { mountedRoutes: { '/search': rootRouteRef } }, ), ], diff --git a/plugins/search/src/components/SearchResult/SearchResult.stories.tsx b/plugins/search/src/components/SearchResult/SearchResult.stories.tsx index c1685df2c1..4a3d950164 100644 --- a/plugins/search/src/components/SearchResult/SearchResult.stories.tsx +++ b/plugins/search/src/components/SearchResult/SearchResult.stories.tsx @@ -19,7 +19,8 @@ import { List, ListItem } from '@material-ui/core'; import React, { ComponentType } from 'react'; import { MemoryRouter } from 'react-router'; import { DefaultResultListItem } from '../DefaultResultListItem'; -import { SearchContextProvider } from '../SearchContext/SearchContextForStorybook.stories'; + +import { SearchContextProviderForStorybook } from '@backstage/plugin-search-react'; import { SearchResult } from './SearchResult'; const mockResults = { @@ -57,9 +58,9 @@ export default { decorators: [ (Story: ComponentType<{}>) => ( - + - + ), ], diff --git a/plugins/search/src/components/SearchType/SearchType.stories.tsx b/plugins/search/src/components/SearchType/SearchType.stories.tsx index 596c4a027a..b56f4c089c 100644 --- a/plugins/search/src/components/SearchType/SearchType.stories.tsx +++ b/plugins/search/src/components/SearchType/SearchType.stories.tsx @@ -19,7 +19,7 @@ import CatalogIcon from '@material-ui/icons/MenuBook'; import DocsIcon from '@material-ui/icons/Description'; import UsersGroupsIcon from '@material-ui/icons/Person'; import React, { ComponentType } from 'react'; -import { SearchContextProvider } from '../SearchContext/SearchContextForStorybook.stories'; +import { SearchContextProviderForStorybook } from '@backstage/plugin-search-react'; import { SearchType } from './SearchType'; export default { @@ -27,13 +27,13 @@ export default { component: SearchType, decorators: [ (Story: ComponentType<{}>) => ( - + - + ), ], }; diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index 8516c09783..b6901e8edd 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -43,7 +43,7 @@ "@backstage/integration": "^1.1.0-next.1", "@backstage/integration-react": "^1.0.1-next.1", "@backstage/plugin-catalog-react": "^1.0.1-next.2", - "@backstage/plugin-search": "^0.7.5-next.0", + "@backstage/plugin-search-react": "^0.0.0", "@backstage/theme": "^0.2.15", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", diff --git a/plugins/techdocs/src/reader/components/Reader.test.tsx b/plugins/techdocs/src/reader/components/Reader.test.tsx index 6e8609694d..09cd33e286 100644 --- a/plugins/techdocs/src/reader/components/Reader.test.tsx +++ b/plugins/techdocs/src/reader/components/Reader.test.tsx @@ -25,7 +25,7 @@ import React from 'react'; import { TechDocsStorageApi, techdocsStorageApiRef } from '../../api'; import { Reader } from './Reader'; import { ApiProvider } from '@backstage/core-app-api'; -import { searchApiRef } from '@backstage/plugin-search'; +import { searchApiRef } from '@backstage/plugin-search-react'; jest.mock('react-router-dom', () => { const actual = jest.requireActual('react-router-dom'); diff --git a/plugins/techdocs/src/reader/components/TechDocsReaderPage.test.tsx b/plugins/techdocs/src/reader/components/TechDocsReaderPage.test.tsx index 55637806a3..9fbf5c2195 100644 --- a/plugins/techdocs/src/reader/components/TechDocsReaderPage.test.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsReaderPage.test.tsx @@ -30,7 +30,7 @@ import { TechDocsStorageApi, } from '../../api'; import { ApiProvider } from '@backstage/core-app-api'; -import { searchApiRef } from '@backstage/plugin-search'; +import { searchApiRef } from '@backstage/plugin-search-react'; jest.mock('react-router-dom', () => { const actual = jest.requireActual('react-router-dom'); diff --git a/plugins/techdocs/src/search/components/TechDocsSearch.test.tsx b/plugins/techdocs/src/search/components/TechDocsSearch.test.tsx index 06d5ac6aac..5957aecc4d 100644 --- a/plugins/techdocs/src/search/components/TechDocsSearch.test.tsx +++ b/plugins/techdocs/src/search/components/TechDocsSearch.test.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ import { ApiProvider } from '@backstage/core-app-api'; -import { searchApiRef } from '@backstage/plugin-search'; +import { searchApiRef } from '@backstage/plugin-search-react'; import { TestApiRegistry, wrapInTestApp } from '@backstage/test-utils'; import { act, diff --git a/plugins/techdocs/src/search/components/TechDocsSearch.tsx b/plugins/techdocs/src/search/components/TechDocsSearch.tsx index 30cc692b7c..f11fa38948 100644 --- a/plugins/techdocs/src/search/components/TechDocsSearch.tsx +++ b/plugins/techdocs/src/search/components/TechDocsSearch.tsx @@ -15,7 +15,10 @@ */ import { CompoundEntityRef } from '@backstage/catalog-model'; -import { SearchContextProvider, useSearch } from '@backstage/plugin-search'; +import { + SearchContextProvider, + useSearch, +} from '@backstage/plugin-search-react'; import { makeStyles, CircularProgress, diff --git a/yarn.lock b/yarn.lock index 4919937660..b5f327b6e4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1478,6 +1478,22 @@ lodash "^4.17.21" uuid "^8.0.0" +"@backstage/core-app-api@^1.0.0": + version "1.0.0" + resolved "https://registry.npmjs.org/@backstage/core-app-api/-/core-app-api-1.0.0.tgz#2dae97b050b2f2e5ec1ea42b3d95c57e8bf434d6" + integrity sha512-hmoFMPCxAfHgDPQTHbf6rquiG0SCSycWTUrScpYeLwkH3UOekgX8o8ThKT0t3w7WPx83LwT0NqcbSH6zqI9nag== + dependencies: + "@backstage/config" "^1.0.0" + "@backstage/core-plugin-api" "^1.0.0" + "@backstage/types" "^1.0.0" + "@backstage/version-bridge" "^1.0.0" + "@types/prop-types" "^15.7.3" + prop-types "^15.7.2" + react-router-dom "6.0.0-beta.0" + react-use "^17.2.4" + zen-observable "^0.8.15" + zod "^3.11.6" + "@backstage/core-components@^0.9.0", "@backstage/core-components@^0.9.2": version "0.9.2" resolved "https://registry.npmjs.org/@backstage/core-components/-/core-components-0.9.2.tgz#9a3d79a15039256bbc007e5daa08c983050e0238" @@ -1602,6 +1618,36 @@ react-use "^17.2.4" swr "^1.1.2" +"@backstage/plugin-search-common@^0.3.2": + version "0.3.2" + resolved "https://registry.npmjs.org/@backstage/plugin-search-common/-/plugin-search-common-0.3.2.tgz#15984ba4c14f8a9119168e8c79344ef8101863dc" + integrity sha512-7vcpRo+5MB/QW/M77zPfcqxw0LzcQCHNXql0uxF+qBwVPJSHz9QB+YBuzGyaAlqfm5UPFXuweLQGqtoB+0DMLg== + dependencies: + "@backstage/plugin-permission-common" "^0.5.3" + "@backstage/types" "^1.0.0" + +"@backstage/test-utils@^1.0.0": + version "1.0.0" + resolved "https://registry.npmjs.org/@backstage/test-utils/-/test-utils-1.0.0.tgz#dafac18065591a7dda584811cb00812495292ee8" + integrity sha512-dHtIjhoq2b+rpsnwVQnWA/2sDxFMt2HL0OxoyKqG2NRum16A7cTQxgrG3UC3p4dqFYKREg7+aTFIjHBa+Tk/PA== + dependencies: + "@backstage/config" "^1.0.0" + "@backstage/core-app-api" "^1.0.0" + "@backstage/core-plugin-api" "^1.0.0" + "@backstage/plugin-permission-common" "^0.5.3" + "@backstage/plugin-permission-react" "^0.3.4" + "@backstage/theme" "^0.2.15" + "@backstage/types" "^1.0.0" + "@material-ui/core" "^4.12.2" + "@material-ui/icons" "^4.11.2" + "@testing-library/jest-dom" "^5.10.1" + "@testing-library/react" "^12.1.3" + "@testing-library/user-event" "^13.1.8" + cross-fetch "^3.1.5" + react-router "6.0.0-beta.0" + react-router-dom "6.0.0-beta.0" + zen-observable "^0.8.15" + "@balena/dockerignore@^1.0.2": version "1.0.2" resolved "https://registry.npmjs.org/@balena/dockerignore/-/dockerignore-1.0.2.tgz#9ffe4726915251e8eb69f44ef3547e0da2c03e0d" @@ -5545,6 +5591,20 @@ lz-string "^1.4.4" pretty-format "^27.0.2" +"@testing-library/dom@^8.5.0": + version "8.13.0" + resolved "https://registry.npmjs.org/@testing-library/dom/-/dom-8.13.0.tgz#bc00bdd64c7d8b40841e27a70211399ad3af46f5" + integrity sha512-9VHgfIatKNXQNaZTtLnalIy0jNZzY35a4S3oi08YAt9Hv1VsfZ/DfA45lM8D/UhtHBGJ4/lGwp0PZkVndRkoOQ== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/runtime" "^7.12.5" + "@types/aria-query" "^4.2.0" + aria-query "^5.0.0" + chalk "^4.1.0" + dom-accessibility-api "^0.5.9" + lz-string "^1.4.4" + pretty-format "^27.0.2" + "@testing-library/jest-dom@^5.10.1": version "5.16.3" resolved "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.3.tgz#b76851a909586113c20486f1679ffb4d8ec27bfa" @@ -5560,6 +5620,21 @@ lodash "^4.17.15" redent "^3.0.0" +"@testing-library/jest-dom@^5.16.4": + version "5.16.4" + resolved "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.4.tgz#938302d7b8b483963a3ae821f1c0808f872245cd" + integrity sha512-Gy+IoFutbMQcky0k+bqqumXZ1cTGswLsFqmNLzNdSKkU9KGV2u9oXhukCbbJ9/LRPKiqwxEE8VpV/+YZlfkPUA== + dependencies: + "@babel/runtime" "^7.9.2" + "@types/testing-library__jest-dom" "^5.9.1" + aria-query "^5.0.0" + chalk "^3.0.0" + css "^3.0.0" + css.escape "^1.5.1" + dom-accessibility-api "^0.5.6" + lodash "^4.17.15" + redent "^3.0.0" + "@testing-library/react-hooks@^7.0.2": version "7.0.2" resolved "https://registry.npmjs.org/@testing-library/react-hooks/-/react-hooks-7.0.2.tgz#3388d07f562d91e7f2431a4a21b5186062ecfee0" @@ -5571,6 +5646,14 @@ "@types/react-test-renderer" ">=16.9.0" react-error-boundary "^3.1.0" +"@testing-library/react-hooks@^8.0.0": + version "8.0.0" + resolved "https://registry.npmjs.org/@testing-library/react-hooks/-/react-hooks-8.0.0.tgz#7d0164bffce4647f506039de0a97f6fcbd20f4bf" + integrity sha512-uZqcgtcUUtw7Z9N32W13qQhVAD+Xki2hxbTR461MKax8T6Jr8nsUvZB+vcBTkzY2nFvsUet434CsgF0ncW2yFw== + dependencies: + "@babel/runtime" "^7.12.5" + react-error-boundary "^3.1.0" + "@testing-library/react@^12.1.3": version "12.1.4" resolved "https://registry.npmjs.org/@testing-library/react/-/react-12.1.4.tgz#09674b117e550af713db3f4ec4c0942aa8bbf2c0" @@ -5580,6 +5663,22 @@ "@testing-library/dom" "^8.0.0" "@types/react-dom" "*" +"@testing-library/react@^13.0.0": + version "13.0.0" + resolved "https://registry.npmjs.org/@testing-library/react/-/react-13.0.0.tgz#8cdaf4667c6c2b082eb0513731551e9db784e8bc" + integrity sha512-p0lYA1M7uoEmk2LnCbZLGmHJHyH59sAaZVXChTXlyhV/PRW9LoIh4mdf7tiXsO8BoNG+vN8UnFJff1hbZeXv+w== + dependencies: + "@babel/runtime" "^7.12.5" + "@testing-library/dom" "^8.5.0" + "@types/react-dom" "*" + +"@testing-library/user-event@^13.1.8": + version "13.5.0" + resolved "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz#69d77007f1e124d55314a2b73fd204b333b13295" + integrity sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg== + dependencies: + "@babel/runtime" "^7.12.5" + "@testing-library/user-event@^14.0.0": version "14.0.0" resolved "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.0.0.tgz#3906aa6f0e56fd012d73559f5f05c02e63ba18dd" From a39a931b39605fe3de3e035b7a0a69c729c54d24 Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Mon, 11 Apr 2022 11:43:22 +0200 Subject: [PATCH 34/58] search api report Signed-off-by: Emma Indal --- plugins/search/api-report.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/plugins/search/api-report.md b/plugins/search/api-report.md index 1bdd918802..f524652f51 100644 --- a/plugins/search/api-report.md +++ b/plugins/search/api-report.md @@ -81,17 +81,19 @@ export type HomePageSearchBarProps = Partial< // @public (undocumented) export const Router: () => JSX.Element; +// Warning: (tsdoc-at-sign-in-word) The "@" character looks like part of a TSDoc tag; use a backslash to escape it // Warning: (ae-missing-release-tag) "SearchApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public @deprecated (undocumented) export interface SearchApi { // (undocumented) query(query: SearchQuery): Promise; } +// Warning: (tsdoc-at-sign-in-word) The "@" character looks like part of a TSDoc tag; use a backslash to escape it // Warning: (ae-missing-release-tag) "searchApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public @deprecated (undocumented) export const searchApiRef: ApiRef; // @public (undocumented) @@ -138,9 +140,10 @@ export const SearchBarNext: ({ // @public export type SearchBarProps = Partial; +// Warning: (tsdoc-at-sign-in-word) The "@" character looks like part of a TSDoc tag; use a backslash to escape it // Warning: (ae-missing-release-tag) "SearchContextProvider" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public @deprecated (undocumented) export const SearchContextProvider: ({ initialState, children, @@ -322,10 +325,11 @@ export type SidebarSearchProps = { icon?: IconComponent; }; +// Warning: (tsdoc-at-sign-in-word) The "@" character looks like part of a TSDoc tag; use a backslash to escape it // Warning: (ae-forgotten-export) The symbol "SearchContextValue" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "useSearch" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public @deprecated (undocumented) export const useSearch: () => SearchContextValue; // @public From 6a4f081128a47bc86fbcf4d9885303ca2e8025fe Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Mon, 11 Apr 2022 12:08:29 +0200 Subject: [PATCH 35/58] let template logos live in home plugin for now Signed-off-by: Emma Indal --- .../home/templates/DefaultTemplate.stories.tsx | 4 ++-- plugins/home/api-report.md | 13 +++++++++++++ .../home/src/assets}/TemplateBackstageLogo.tsx | 2 +- .../home/src/assets}/TemplateBackstageLogoIcon.tsx | 1 - .../templates => plugins/home/src/assets}/index.ts | 6 +++--- .../CompanyLogo/CompanyLogo.stories.tsx | 2 +- .../homePageComponents/Toolkit/Toolkit.stories.tsx | 2 +- plugins/home/src/index.ts | 1 + 8 files changed, 22 insertions(+), 9 deletions(-) rename {packages/app/src/components/home/templates => plugins/home/src/assets}/TemplateBackstageLogo.tsx (99%) rename {packages/app/src/components/home/templates => plugins/home/src/assets}/TemplateBackstageLogoIcon.tsx (99%) rename {packages/app/src/components/home/templates => plugins/home/src/assets}/index.ts (76%) diff --git a/packages/app/src/components/home/templates/DefaultTemplate.stories.tsx b/packages/app/src/components/home/templates/DefaultTemplate.stories.tsx index b2f6034709..8b9c5100b1 100644 --- a/packages/app/src/components/home/templates/DefaultTemplate.stories.tsx +++ b/packages/app/src/components/home/templates/DefaultTemplate.stories.tsx @@ -14,12 +14,12 @@ * limitations under the License. */ -import { TemplateBackstageLogo } from './TemplateBackstageLogo'; -import { TemplateBackstageLogoIcon } from './TemplateBackstageLogoIcon'; import { HomePageToolkit, HomePageCompanyLogo, HomePageStarredEntities, + TemplateBackstageLogo, + TemplateBackstageLogoIcon } from '@backstage/plugin-home'; import { wrapInTestApp, TestApiProvider } from '@backstage/test-utils'; import { Content, Page, InfoCard } from '@backstage/core-components'; diff --git a/plugins/home/api-report.md b/plugins/home/api-report.md index 9bd577da7c..21c5592636 100644 --- a/plugins/home/api-report.md +++ b/plugins/home/api-report.md @@ -119,11 +119,24 @@ export const SettingsModal: (props: { children: JSX.Element; }) => JSX.Element; +// Warning: (ae-missing-release-tag) "TemplateBackstageLogo" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const TemplateBackstageLogo: (props: { + classes: Classes; +}) => JSX.Element; + +// Warning: (ae-missing-release-tag) "TemplateBackstageLogoIcon" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const TemplateBackstageLogoIcon: () => JSX.Element; + // @public export const WelcomeTitle: () => JSX.Element; // Warnings were encountered during analysis: // +// src/assets/TemplateBackstageLogo.d.ts:7:5 - (ae-forgotten-export) The symbol "Classes" needs to be exported by the entry point index.d.ts // src/extensions.d.ts:6:5 - (ae-forgotten-export) The symbol "RendererProps" needs to be exported by the entry point index.d.ts // src/extensions.d.ts:27:5 - (ae-forgotten-export) The symbol "ComponentParts" needs to be exported by the entry point index.d.ts ``` diff --git a/packages/app/src/components/home/templates/TemplateBackstageLogo.tsx b/plugins/home/src/assets/TemplateBackstageLogo.tsx similarity index 99% rename from packages/app/src/components/home/templates/TemplateBackstageLogo.tsx rename to plugins/home/src/assets/TemplateBackstageLogo.tsx index edce9bb02e..0fc908ee39 100644 --- a/packages/app/src/components/home/templates/TemplateBackstageLogo.tsx +++ b/plugins/home/src/assets/TemplateBackstageLogo.tsx @@ -19,7 +19,7 @@ import React from 'react'; type Classes = { svg: string; path: string; -} +}; export const TemplateBackstageLogo = (props: { classes: Classes }) => { return ( diff --git a/packages/app/src/components/home/templates/TemplateBackstageLogoIcon.tsx b/plugins/home/src/assets/TemplateBackstageLogoIcon.tsx similarity index 99% rename from packages/app/src/components/home/templates/TemplateBackstageLogoIcon.tsx rename to plugins/home/src/assets/TemplateBackstageLogoIcon.tsx index 2116b48784..09c4405286 100644 --- a/packages/app/src/components/home/templates/TemplateBackstageLogoIcon.tsx +++ b/plugins/home/src/assets/TemplateBackstageLogoIcon.tsx @@ -43,4 +43,3 @@ export const TemplateBackstageLogoIcon = () => { ); }; - diff --git a/packages/app/src/components/home/templates/index.ts b/plugins/home/src/assets/index.ts similarity index 76% rename from packages/app/src/components/home/templates/index.ts rename to plugins/home/src/assets/index.ts index bfebe73cd8..79de43ca99 100644 --- a/packages/app/src/components/home/templates/index.ts +++ b/plugins/home/src/assets/index.ts @@ -1,5 +1,5 @@ /* - * Copyright 2021 The Backstage Authors + * 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. @@ -14,5 +14,5 @@ * limitations under the License. */ -export { TemplateBackstageLogoIcon } from './TemplateBackstageLogoIcon'; -export { TemplateBackstageLogo } from './TemplateBackstageLogo' +export * from './TemplateBackstageLogo'; +export * from './TemplateBackstageLogoIcon'; diff --git a/plugins/home/src/homePageComponents/CompanyLogo/CompanyLogo.stories.tsx b/plugins/home/src/homePageComponents/CompanyLogo/CompanyLogo.stories.tsx index ab71eea54e..741ad2e977 100644 --- a/plugins/home/src/homePageComponents/CompanyLogo/CompanyLogo.stories.tsx +++ b/plugins/home/src/homePageComponents/CompanyLogo/CompanyLogo.stories.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import { TemplateBackstageLogo } from '../../templates'; +import { TemplateBackstageLogo } from '../../assets'; import { HomePageCompanyLogo } from '../../plugin'; import { rootRouteRef } from '../../routes'; import { wrapInTestApp, TestApiProvider } from '@backstage/test-utils'; diff --git a/plugins/home/src/homePageComponents/Toolkit/Toolkit.stories.tsx b/plugins/home/src/homePageComponents/Toolkit/Toolkit.stories.tsx index cad188c5d6..9a82301e49 100644 --- a/plugins/home/src/homePageComponents/Toolkit/Toolkit.stories.tsx +++ b/plugins/home/src/homePageComponents/Toolkit/Toolkit.stories.tsx @@ -20,7 +20,7 @@ import { Grid } from '@material-ui/core'; import React, { ComponentType } from 'react'; import { ComponentAccordion } from '../../componentRenderers'; import { HomePageToolkit } from '../../plugin'; -import { TemplateBackstageLogoIcon } from '../../templates'; +import { TemplateBackstageLogoIcon } from '../../assets'; export default { title: 'Plugins/Home/Components/Toolkit', diff --git a/plugins/home/src/index.ts b/plugins/home/src/index.ts index d30b76a7fc..8f137d589b 100644 --- a/plugins/home/src/index.ts +++ b/plugins/home/src/index.ts @@ -33,6 +33,7 @@ export { WelcomeTitle, } from './plugin'; export { SettingsModal, HeaderWorldClock } from './components'; +export * from './assets'; export type { ClockConfig } from './components'; export { createCardExtension } from './extensions'; export type { ComponentRenderer } from './extensions'; From 57f05a2c294ed06db24c9e056be466466592756d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Mon, 11 Apr 2022 13:36:06 +0200 Subject: [PATCH 36/58] bump webpack-dev-server MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- yarn.lock | 119 ++++++++++++++++++++---------------------------------- 1 file changed, 43 insertions(+), 76 deletions(-) diff --git a/yarn.lock b/yarn.lock index fb3bb08459..b9cf5fdd60 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3488,6 +3488,11 @@ underscore "^1.9.1" ws "^7.3.1" +"@leichtgewicht/ip-codec@^2.0.1": + version "2.0.3" + resolved "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.3.tgz#0300943770e04231041a51bd39f0439b5c7ab4f0" + integrity sha512-nkalE/f1RvRGChwBnEIoBfSEYOXnCRdleKuv6+lePbMDrMZXeDQnqak5XDOeBgrPPyPfAdcCu/B5z+v3VhplGg== + "@lerna/add@4.0.0": version "4.0.0" resolved "https://registry.npmjs.org/@lerna/add/-/add-4.0.0.tgz#c36f57d132502a57b9e7058d1548b7a565ef183f" @@ -6982,10 +6987,10 @@ dependencies: "@types/node" "*" -"@types/ws@^8.0.0", "@types/ws@^8.2.2": - version "8.2.2" - resolved "https://registry.npmjs.org/@types/ws/-/ws-8.2.2.tgz#7c5be4decb19500ae6b3d563043cd407bf366c21" - integrity sha512-NOn5eIcgWLOo6qW8AcuLZ7G8PycXu0xTxxkS6Q18VWFxgPUSOwV0pBj2a/4viNZVu25i7RIB7GttdkAIUUXOOg== +"@types/ws@^8.0.0", "@types/ws@^8.5.1": + version "8.5.3" + resolved "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d" + integrity sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w== dependencies: "@types/node" "*" @@ -7853,7 +7858,7 @@ array-flatten@1.1.1: resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= -array-flatten@^2.1.0: +array-flatten@^2.1.2: version "2.1.2" resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== @@ -8510,17 +8515,15 @@ body-parser@1.19.2, body-parser@^1.19.0: raw-body "2.4.3" type-is "~1.6.18" -bonjour@^3.5.0: - version "3.5.0" - resolved "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" - integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU= +bonjour-service@^1.0.11: + version "1.0.11" + resolved "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.0.11.tgz#5418e5c1ac91c89a406f853a942e7892829c0d89" + integrity sha512-drMprzr2rDTCtgEE3VgdA9uUFaUHF+jXduwYSThHJnKMYM+FhI9Z3ph+TX3xy0LtgYHae6CHYPJ/2UnK8nQHcA== dependencies: - array-flatten "^2.1.0" - deep-equal "^1.0.1" + array-flatten "^2.1.2" dns-equal "^1.0.0" - dns-txt "^2.0.2" - multicast-dns "^6.0.1" - multicast-dns-service-types "^1.1.0" + fast-deep-equal "^3.1.3" + multicast-dns "^7.2.4" boolbase@^1.0.0: version "1.0.0" @@ -8727,11 +8730,6 @@ buffer-indexof-polyfill@~1.0.0: resolved "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz#d2732135c5999c64b277fcf9b1abe3498254729c" integrity sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A== -buffer-indexof@^1.0.0: - version "1.1.1" - resolved "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" - integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g== - buffer-writer@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz#ce7eb81a38f7829db09c873f2fbb792c0c98ec04" @@ -10864,18 +10862,6 @@ dedent@^0.7.0: resolved "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= -deep-equal@^1.0.1: - version "1.1.1" - resolved "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" - integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== - dependencies: - is-arguments "^1.0.4" - is-date-object "^1.0.1" - is-regex "^1.0.4" - object-is "^1.0.1" - object-keys "^1.1.1" - regexp.prototype.flags "^1.2.0" - deep-extend@0.6.0, deep-extend@^0.6.0: version "0.6.0" resolved "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" @@ -11150,20 +11136,12 @@ dns-equal@^1.0.0: resolved "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= -dns-packet@^1.3.1: - version "1.3.4" - resolved "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.4.tgz#e3455065824a2507ba886c55a89963bb107dec6f" - integrity sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA== +dns-packet@^5.2.2: + version "5.3.1" + resolved "https://registry.npmjs.org/dns-packet/-/dns-packet-5.3.1.tgz#eb94413789daec0f0ebe2fcc230bdc9d7c91b43d" + integrity sha512-spBwIj0TK0Ey3666GwIdWVfUpLyubpU53BTCu8iPn4r4oXd9O14Hjg3EHw3ts2oed77/SeckunUYCyRlSngqHw== dependencies: - ip "^1.1.0" - safe-buffer "^5.0.1" - -dns-txt@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" - integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY= - dependencies: - buffer-indexof "^1.0.0" + "@leichtgewicht/ip-codec" "^2.0.1" docker-compose@^0.23.17: version "0.23.17" @@ -12384,7 +12362,7 @@ express-xml-bodyparser@^0.3.0: dependencies: xml2js "^0.4.11" -express@^4.17.1: +express@^4.17.1, express@^4.17.3: version "4.17.3" resolved "https://registry.npmjs.org/express/-/express-4.17.3.tgz#f6c7302194a4fb54271b73a1fe7a06478c8f85a1" integrity sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg== @@ -14083,7 +14061,7 @@ http-proxy-agent@^5.0.0: agent-base "6" debug "4" -http-proxy-middleware@^2.0.0: +http-proxy-middleware@^2.0.0, http-proxy-middleware@^2.0.3: version "2.0.4" resolved "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.4.tgz#03af0f4676d172ae775cb5c33f592f40e1a4e07a" integrity sha512-m/4FxX17SUvz4lJ5WPXOHDUuCwIqXLfLHs1s0uZ3oYjhoXlx9csYxaOa0ElDEJ+h8Q4iJ1s+lTMbiCa4EXIJqg== @@ -14515,7 +14493,7 @@ ioredis@^4.28.5: redis-parser "^3.0.0" standard-as-callback "^2.1.0" -ip@^1.1.0, ip@^1.1.5: +ip@^1.1.5: version "1.1.5" resolved "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= @@ -14956,7 +14934,7 @@ is-reference@^1.2.1: dependencies: "@types/estree" "*" -is-regex@^1.0.4, is-regex@^1.1.4: +is-regex@^1.1.4: version "1.1.4" resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== @@ -18232,17 +18210,12 @@ msw@^0.36.3: type-fest "^1.2.2" yargs "^17.3.0" -multicast-dns-service-types@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" - integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE= - -multicast-dns@^6.0.1: - version "6.2.3" - resolved "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229" - integrity sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g== +multicast-dns@^7.2.4: + version "7.2.4" + resolved "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.4.tgz#cf0b115c31e922aeb20b64e6556cbeb34cf0dd19" + integrity sha512-XkCYOU+rr2Ft3LI6w4ye51M3VK31qJXFIxu0XLw169PtKG0Zx47OrXeVW/GCYOfpC9s1yyyf1S+L8/4LY0J9Zw== dependencies: - dns-packet "^1.3.1" + dns-packet "^5.2.2" thunky "^1.0.2" multimatch@^5.0.0: @@ -18831,11 +18804,6 @@ object-inspect@^1.11.0, object-inspect@^1.12.0, object-inspect@^1.9.0: resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== -object-is@^1.0.1: - version "1.0.2" - resolved "https://registry.npmjs.org/object-is/-/object-is-1.0.2.tgz#6b80eb84fe451498f65007982f035a5b445edec4" - integrity sha512-Epah+btZd5wrrfjkJZq1AOB9O6OxUQto45hzFd7lXGrpHPGE0W1k+426yrZV+k6NJOzLNNW/nVsmZdIWsAqoOQ== - object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" @@ -21596,7 +21564,7 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" -regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.3.1: +regexp.prototype.flags@^1.3.1: version "1.4.1" resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.1.tgz#b3f4c0059af9e47eca9f3f660e51d81307e72307" integrity sha512-pMR7hBVUUGI7PMA37m2ofIdQCsomVnas+Jn5UPGAHQ+/LlwKm/aTLJHdasmHRzlfeZwHiAOaRSo2rbBDm3nNUQ== @@ -22265,7 +22233,7 @@ select-hose@^2.0.0: resolved "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= -selfsigned@^2.0.0: +selfsigned@^2.0.0, selfsigned@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/selfsigned/-/selfsigned-2.0.1.tgz#8b2df7fa56bf014d19b6007655fff209c0ef0a56" integrity sha512-LmME957M1zOsUhG+67rAjKfiWFox3SBxE/yymatMZsAx+oMrJ0YQ8AToOnyCm7xbeg2ep37IHLxdu0o2MavQOQ== @@ -23307,7 +23275,7 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" -strip-ansi@^7.0.0, strip-ansi@^7.0.1: +strip-ansi@^7.0.1: version "7.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== @@ -25155,38 +25123,37 @@ webpack-dev-middleware@^5.3.1: schema-utils "^4.0.0" webpack-dev-server@^4.7.3: - version "4.7.4" - resolved "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.7.4.tgz#d0ef7da78224578384e795ac228d8efb63d5f945" - integrity sha512-nfdsb02Zi2qzkNmgtZjkrMOcXnYZ6FLKcQwpxT7MvmHKc+oTtDsBju8j+NMyAygZ9GW1jMEUpy3itHtqgEhe1A== + version "4.8.1" + resolved "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.8.1.tgz#58f9d797710d6e25fa17d6afab8708f958c11a29" + integrity sha512-dwld70gkgNJa33czmcj/PlKY/nOy/BimbrgZRaR9vDATBQAYgLzggR0nxDtPLJiLrMgZwbE6RRfJ5vnBBasTyg== dependencies: "@types/bonjour" "^3.5.9" "@types/connect-history-api-fallback" "^1.3.5" "@types/express" "^4.17.13" "@types/serve-index" "^1.9.1" "@types/sockjs" "^0.3.33" - "@types/ws" "^8.2.2" + "@types/ws" "^8.5.1" ansi-html-community "^0.0.8" - bonjour "^3.5.0" + bonjour-service "^1.0.11" chokidar "^3.5.3" colorette "^2.0.10" compression "^1.7.4" connect-history-api-fallback "^1.6.0" default-gateway "^6.0.3" - del "^6.0.0" - express "^4.17.1" + express "^4.17.3" graceful-fs "^4.2.6" html-entities "^2.3.2" - http-proxy-middleware "^2.0.0" + http-proxy-middleware "^2.0.3" ipaddr.js "^2.0.1" open "^8.0.9" p-retry "^4.5.0" portfinder "^1.0.28" + rimraf "^3.0.2" schema-utils "^4.0.0" - selfsigned "^2.0.0" + selfsigned "^2.0.1" serve-index "^1.9.1" sockjs "^0.3.21" spdy "^4.0.2" - strip-ansi "^7.0.0" webpack-dev-middleware "^5.3.1" ws "^8.4.2" From c64c33f74ba07b14c1abaf4638be0d66ff84c623 Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Mon, 11 Apr 2022 13:16:38 +0200 Subject: [PATCH 37/58] dependency and docs fixups Signed-off-by: Emma Indal --- packages/app/package.json | 3 ++ plugins/home/README.md | 2 +- plugins/search-react/package.json | 6 +-- yarn.lock | 79 ++----------------------------- 4 files changed, 10 insertions(+), 80 deletions(-) diff --git a/packages/app/package.json b/packages/app/package.json index 4522cabaf1..f8dc6127c8 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -10,6 +10,7 @@ "@backstage/app-defaults": "^1.0.1-next.1", "@backstage/catalog-model": "^1.0.1-next.0", "@backstage/cli": "^0.17.0-next.1", + "@backstage/config": "^1.0.0", "@backstage/core-app-api": "^1.0.1-next.0", "@backstage/core-components": "^0.9.3-next.0", "@backstage/core-plugin-api": "^1.0.0", @@ -47,9 +48,11 @@ "@backstage/plugin-rollbar": "^0.4.4-next.0", "@backstage/plugin-scaffolder": "^1.0.1-next.1", "@backstage/plugin-search": "^0.7.5-next.0", + "@backstage/plugin-search-react": "^0.0.0", "@backstage/plugin-search-common": "^0.3.3-next.1", "@backstage/plugin-sentry": "^0.3.42-next.0", "@backstage/plugin-shortcuts": "^0.2.5-next.0", + "@backstage/plugin-stack-overflow": "^0.1.0-next.0", "@backstage/plugin-tech-radar": "^0.5.11-next.1", "@backstage/plugin-techdocs": "^1.0.1-next.1", "@backstage/plugin-todo": "^0.2.6-next.0", diff --git a/plugins/home/README.md b/plugins/home/README.md index a85994b3cb..0cd307b706 100644 --- a/plugins/home/README.md +++ b/plugins/home/README.md @@ -93,4 +93,4 @@ Additionally, the API is at a very early state, so contributing with additional ### Homepage Templates -We are hoping that we together can build up a collection of Homepage templates. We therefore put together a place where we can collect all the templates for the Home Plugin in the [storybook](https://backstage.io/storybook/?path=/story/plugins-home-templates). If you would like to contribute with a template, start by taking a look at the [DefaultTemplate storybook example to create your own](/plugins/home/src/templates/DefaultTemplate.stories.tsx), and then open a PR with your suggestion. +We are hoping that we together can build up a collection of Homepage templates. We therefore put together a place where we can collect all the templates for the Home Plugin in the [storybook](https://backstage.io/storybook/?path=/story/plugins-home-templates). If you would like to contribute with a template, start by taking a look at the [DefaultTemplate storybook example to create your own](/packages/app/src/components/home/templates/DefaultTemplate.stories.tsx), and then open a PR with your suggestion. diff --git a/plugins/search-react/package.json b/plugins/search-react/package.json index 66b6bdfa46..15251b4ac7 100644 --- a/plugins/search-react/package.json +++ b/plugins/search-react/package.json @@ -31,7 +31,7 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/plugin-search-common": "^0.3.2", + "@backstage/plugin-search-common": "^0.3.3-next.1", "@backstage/core-plugin-api": "^1.0.0", "@backstage/core-app-api": "^1.0.1-next.0", "react-use": "^17.3.2", @@ -42,8 +42,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/test-utils": "^1.0.0", - "@testing-library/react": "^13.0.0", + "@backstage/test-utils": "^1.0.1-next.1", + "@testing-library/react": "^12.1.3", "@testing-library/react-hooks": "^8.0.0", "@testing-library/jest-dom": "^5.16.4" }, diff --git a/yarn.lock b/yarn.lock index b5f327b6e4..223c451347 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1478,22 +1478,6 @@ lodash "^4.17.21" uuid "^8.0.0" -"@backstage/core-app-api@^1.0.0": - version "1.0.0" - resolved "https://registry.npmjs.org/@backstage/core-app-api/-/core-app-api-1.0.0.tgz#2dae97b050b2f2e5ec1ea42b3d95c57e8bf434d6" - integrity sha512-hmoFMPCxAfHgDPQTHbf6rquiG0SCSycWTUrScpYeLwkH3UOekgX8o8ThKT0t3w7WPx83LwT0NqcbSH6zqI9nag== - dependencies: - "@backstage/config" "^1.0.0" - "@backstage/core-plugin-api" "^1.0.0" - "@backstage/types" "^1.0.0" - "@backstage/version-bridge" "^1.0.0" - "@types/prop-types" "^15.7.3" - prop-types "^15.7.2" - react-router-dom "6.0.0-beta.0" - react-use "^17.2.4" - zen-observable "^0.8.15" - zod "^3.11.6" - "@backstage/core-components@^0.9.0", "@backstage/core-components@^0.9.2": version "0.9.2" resolved "https://registry.npmjs.org/@backstage/core-components/-/core-components-0.9.2.tgz#9a3d79a15039256bbc007e5daa08c983050e0238" @@ -1618,36 +1602,6 @@ react-use "^17.2.4" swr "^1.1.2" -"@backstage/plugin-search-common@^0.3.2": - version "0.3.2" - resolved "https://registry.npmjs.org/@backstage/plugin-search-common/-/plugin-search-common-0.3.2.tgz#15984ba4c14f8a9119168e8c79344ef8101863dc" - integrity sha512-7vcpRo+5MB/QW/M77zPfcqxw0LzcQCHNXql0uxF+qBwVPJSHz9QB+YBuzGyaAlqfm5UPFXuweLQGqtoB+0DMLg== - dependencies: - "@backstage/plugin-permission-common" "^0.5.3" - "@backstage/types" "^1.0.0" - -"@backstage/test-utils@^1.0.0": - version "1.0.0" - resolved "https://registry.npmjs.org/@backstage/test-utils/-/test-utils-1.0.0.tgz#dafac18065591a7dda584811cb00812495292ee8" - integrity sha512-dHtIjhoq2b+rpsnwVQnWA/2sDxFMt2HL0OxoyKqG2NRum16A7cTQxgrG3UC3p4dqFYKREg7+aTFIjHBa+Tk/PA== - dependencies: - "@backstage/config" "^1.0.0" - "@backstage/core-app-api" "^1.0.0" - "@backstage/core-plugin-api" "^1.0.0" - "@backstage/plugin-permission-common" "^0.5.3" - "@backstage/plugin-permission-react" "^0.3.4" - "@backstage/theme" "^0.2.15" - "@backstage/types" "^1.0.0" - "@material-ui/core" "^4.12.2" - "@material-ui/icons" "^4.11.2" - "@testing-library/jest-dom" "^5.10.1" - "@testing-library/react" "^12.1.3" - "@testing-library/user-event" "^13.1.8" - cross-fetch "^3.1.5" - react-router "6.0.0-beta.0" - react-router-dom "6.0.0-beta.0" - zen-observable "^0.8.15" - "@balena/dockerignore@^1.0.2": version "1.0.2" resolved "https://registry.npmjs.org/@balena/dockerignore/-/dockerignore-1.0.2.tgz#9ffe4726915251e8eb69f44ef3547e0da2c03e0d" @@ -5591,20 +5545,6 @@ lz-string "^1.4.4" pretty-format "^27.0.2" -"@testing-library/dom@^8.5.0": - version "8.13.0" - resolved "https://registry.npmjs.org/@testing-library/dom/-/dom-8.13.0.tgz#bc00bdd64c7d8b40841e27a70211399ad3af46f5" - integrity sha512-9VHgfIatKNXQNaZTtLnalIy0jNZzY35a4S3oi08YAt9Hv1VsfZ/DfA45lM8D/UhtHBGJ4/lGwp0PZkVndRkoOQ== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/runtime" "^7.12.5" - "@types/aria-query" "^4.2.0" - aria-query "^5.0.0" - chalk "^4.1.0" - dom-accessibility-api "^0.5.9" - lz-string "^1.4.4" - pretty-format "^27.0.2" - "@testing-library/jest-dom@^5.10.1": version "5.16.3" resolved "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.3.tgz#b76851a909586113c20486f1679ffb4d8ec27bfa" @@ -5663,22 +5603,6 @@ "@testing-library/dom" "^8.0.0" "@types/react-dom" "*" -"@testing-library/react@^13.0.0": - version "13.0.0" - resolved "https://registry.npmjs.org/@testing-library/react/-/react-13.0.0.tgz#8cdaf4667c6c2b082eb0513731551e9db784e8bc" - integrity sha512-p0lYA1M7uoEmk2LnCbZLGmHJHyH59sAaZVXChTXlyhV/PRW9LoIh4mdf7tiXsO8BoNG+vN8UnFJff1hbZeXv+w== - dependencies: - "@babel/runtime" "^7.12.5" - "@testing-library/dom" "^8.5.0" - "@types/react-dom" "*" - -"@testing-library/user-event@^13.1.8": - version "13.5.0" - resolved "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz#69d77007f1e124d55314a2b73fd204b333b13295" - integrity sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg== - dependencies: - "@babel/runtime" "^7.12.5" - "@testing-library/user-event@^14.0.0": version "14.0.0" resolved "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.0.0.tgz#3906aa6f0e56fd012d73559f5f05c02e63ba18dd" @@ -12267,6 +12191,7 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: "@backstage/app-defaults" "^1.0.1-next.1" "@backstage/catalog-model" "^1.0.1-next.0" "@backstage/cli" "^0.17.0-next.1" + "@backstage/config" "^1.0.0" "@backstage/core-app-api" "^1.0.1-next.0" "@backstage/core-components" "^0.9.3-next.0" "@backstage/core-plugin-api" "^1.0.0" @@ -12305,8 +12230,10 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: "@backstage/plugin-scaffolder" "^1.0.1-next.1" "@backstage/plugin-search" "^0.7.5-next.0" "@backstage/plugin-search-common" "^0.3.3-next.1" + "@backstage/plugin-search-react" "^0.0.0" "@backstage/plugin-sentry" "^0.3.42-next.0" "@backstage/plugin-shortcuts" "^0.2.5-next.0" + "@backstage/plugin-stack-overflow" "^0.1.0-next.0" "@backstage/plugin-tech-insights" "^0.1.14-next.0" "@backstage/plugin-tech-radar" "^0.5.11-next.1" "@backstage/plugin-techdocs" "^1.0.1-next.1" From f3bd34aa3b9b1a6c25b4e5722e98200e2ab34405 Mon Sep 17 00:00:00 2001 From: Jose Badeau Date: Wed, 6 Apr 2022 09:05:20 +0200 Subject: [PATCH 38/58] Added SIX MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jose Badeau Signed-off-by: Fredrik Adelöw --- ADOPTERS.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ADOPTERS.md b/ADOPTERS.md index 006dc071cd..c184d00267 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -26,7 +26,7 @@ _If you're using Backstage in your organization, please try to add your company | [Acast.com](https://acast.com) | [Olle Lundberg](https://github.com/lndbrg) | Developer portal with tech docs, service catalog and a bunch of other internal tooling | | [Lunar](https://lunar.app) | [Jacob Valdemar](https://github.com/JacobValdemar) | Internal developer portal for service overview and insights, API documentation, technical guides, onboarding guides and RFC's. | | [Trendyol](https://trendyol.com) | [Gamze Senturk](https://github.com/gmzsenturk), [Mert Can Bilgic](https://github.com/mertcb) | The Developer Portal has been called `Pandora`. Provides an overview of Trendyol tech ecosystem. TechDocs, Catalog, Custom Plugins and Theme. | -| [Peloton](https://www.onepeloton.com/) | [Matt Waldron](https://github.com/daftgopher) | Creating our first developer portal and tech-docs. Exploring Service Catalog, Tech Insights and Cost Insights as well. | +| [Peloton](https://www.onepeloton.com/) | [Matt Waldron](https://github.com/daftgopher) | Creating our first developer portal and tech-docs. Exploring Service Catalog, Tech Insights and Cost Insights as well. | | [TELUS](https://telus.com) | [Seb Barre](https://github.com/sbarre) | The Go-to place to find answers about development and delivery at TELUS. | | [Brex](https://www.brex.com/) | [Vamsi Chitters](https://github.com/vamsikc) | A centralized UI to understand how a service fits in the whole Brex architecture and manage a team’s engineering dependencies. | | [Oriflame](https://www.oriflame.com/) | [Oriflame](https://github.com/oriflame) | Internal developer portal for services, single page apps and packages overview, API documentation, technical guides, tech-radar and more. | @@ -34,7 +34,7 @@ _If you're using Backstage in your organization, please try to add your company | [Netflix](https://www.netflix.com/) | [bleathem](https://github.com/bleathem) | Our Backstage implementation will be the front door to a unified experience connecting our internal platform products across important workflows with integrated knowledge and support. | | [b.well](https://www.icanbwell.com/) | [Jacob Rosales](https://github.com/jrosales) | Foundation for our engineering portal and cloud insights. | | [PagerDuty](https://www.pagerduty.com/) | [Mark Shaw](https://github.com/markshawtoronto) | Developer portal, initially focused on software templates and tech-docs. | -| [MoonShiner](https://moonshiner.at) | [Fabian Hippmann](https://github.com/FabianHippmann) | Developer portal - helps us keep track of our customer projects, onboard new developers & improve our development process 🌕🚀🧑‍🚀 | +| [MoonShiner](https://moonshiner.at) | [Fabian Hippmann](https://github.com/FabianHippmann) | Developer portal - helps us keep track of our customer projects, onboard new developers & improve our development process 🌕🚀🧑‍🚀 | | [FundApps](https://www.fundapps.co/) | [Elliot Greenwood](https://github.com/egnwd) | Developer Portal - A place for us to keep track of our projects and documentation for all services and processes | | [DAZN](https://dazn.com/) | [Lou Bichard](https://twitter.com/loujaybee), [Marco Crivellaro](https://github.com/crivetechie), [Alex Hollerith](mailto:alex.hollerith@dazn.com) | Ingesting all of DAZN's repos for the catalog, migrating our internal platform apps (pull request boards, release information, inner source marketplace etc) to Backstage plugins (where applicable). | | [HelloFresh](https://www.hellofresh.de/) | [@iammuho](https://github.com/iammuho), [@ElenaForester](https://github.com/ElenaForester), [@diegomarangoni](https://github.com/diegomarangoni) | Our developer portal at HelloFresh - Spread across an organisation of 500+ engineers globally. | @@ -110,3 +110,4 @@ _If you're using Backstage in your organization, please try to add your company | [Beez Innovation Labs Pvt. Ltd](https://www.beezlabs.com/) | [Karthikeyan Venkatesan](https://github.com/karthikeyan23) | Developer portal with software catalog, scaffolding, tech docs, templates, and infra. | | [Agorapulse](https://www.agorapulse.com/) | [@jvdrean](https://github.com/jvdrean) | Developer portal with software catalog, documentation, monitoring, runbooks, tech radar and more. | | [Wistia](https://wistia.com/) | [@qrush](https://github.com/qrush), [@okize](https://github.com/okize) | Internal Developer Portal, service catalog, tech docs and more | +| [SIX](https://www.six-group.com/) | [@jbadeau](https://github.com/jbadeau), [@tomassatka](https://github.com/tomassatka) | Internal DevOps portal hosting our software and dataset catalog, as well as custom plugins for observability, service virtualization, deployments, incident managment and quality metrics. | From de6045a8645f6c6be56d8c451c107ea99f658ac6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Sat, 9 Apr 2022 14:33:41 +0200 Subject: [PATCH 39/58] add RBI as an adopter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- ADOPTERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ADOPTERS.md b/ADOPTERS.md index c184d00267..f6529e505c 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -111,3 +111,4 @@ _If you're using Backstage in your organization, please try to add your company | [Agorapulse](https://www.agorapulse.com/) | [@jvdrean](https://github.com/jvdrean) | Developer portal with software catalog, documentation, monitoring, runbooks, tech radar and more. | | [Wistia](https://wistia.com/) | [@qrush](https://github.com/qrush), [@okize](https://github.com/okize) | Internal Developer Portal, service catalog, tech docs and more | | [SIX](https://www.six-group.com/) | [@jbadeau](https://github.com/jbadeau), [@tomassatka](https://github.com/tomassatka) | Internal DevOps portal hosting our software and dataset catalog, as well as custom plugins for observability, service virtualization, deployments, incident managment and quality metrics. | +| [Raiffeisen Bank International](https://www.rbinternational.com/) | [Daniel Baumgartner](https://github.com/dabarbi) | From developers for developers: software catalog, techdocs and heavy use of scaffolder to drive reuse on engineering level forward. Part of inner source initiative. Multi national setup coming. | From d96e7f2f764046eba7a6a290cdc465de7bd59bee Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Apr 2022 04:27:26 +0000 Subject: [PATCH 40/58] build(deps): bump @microsoft/api-extractor-model from 7.16.0 to 7.16.1 Bumps [@microsoft/api-extractor-model](https://github.com/microsoft/rushstack/tree/HEAD/libraries/api-extractor-model) from 7.16.0 to 7.16.1. - [Release notes](https://github.com/microsoft/rushstack/releases) - [Changelog](https://github.com/microsoft/rushstack/blob/main/libraries/api-extractor-model/CHANGELOG.md) - [Commits](https://github.com/microsoft/rushstack/commits/@microsoft/api-extractor-model_v7.16.1/libraries/api-extractor-model) --- updated-dependencies: - dependency-name: "@microsoft/api-extractor-model" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- yarn.lock | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index b9cf5fdd60..9b08e78fe5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4369,7 +4369,7 @@ "@microsoft/tsdoc-config" "~0.15.2" "@rushstack/node-core-library" "3.45.0" -"@microsoft/api-extractor-model@7.16.0", "@microsoft/api-extractor-model@^7.16.0": +"@microsoft/api-extractor-model@7.16.0": version "7.16.0" resolved "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.16.0.tgz#3db7360897115f26a857f1f684fb5af82b0ef9f6" integrity sha512-0FOrbNIny8mzBrzQnSIkEjAXk0JMSnPmWYxt3ZDTPVg9S8xIPzB6lfgTg9+Mimu0RKCpGKBpd+v2WcR5vGzyUQ== @@ -4378,6 +4378,15 @@ "@microsoft/tsdoc-config" "~0.15.2" "@rushstack/node-core-library" "3.45.1" +"@microsoft/api-extractor-model@^7.16.0": + version "7.16.1" + resolved "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.16.1.tgz#f6e53614e90c8a6be47bad5b91d49cc6d8c5c2bf" + integrity sha512-+1mlvy/ji+mUuH7WdVZ6fTo/aCKfS6m37aAFVOFWLfkMvmR+I9SjPfiv9qOg83If7GOrk2HPiHHibv6kA80VTg== + dependencies: + "@microsoft/tsdoc" "0.13.2" + "@microsoft/tsdoc-config" "~0.15.2" + "@rushstack/node-core-library" "3.45.2" + "@microsoft/api-extractor@^7.19.4": version "7.19.4" resolved "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.19.4.tgz#95d43d410a1dfb28a02062c4693bcb9c52afe9eb" @@ -5270,6 +5279,21 @@ timsort "~0.3.0" z-schema "~5.0.2" +"@rushstack/node-core-library@3.45.2": + version "3.45.2" + resolved "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.45.2.tgz#68fc89c5bea4007359fa4ff203bf3eca27037f40" + integrity sha512-MJKdB6mxOoIkks3htGVCo7aiTzllm2I6Xua+KbTSb0cp7rBp8gTCOF/4d8R4HFMwpRdEdwzKgqMM6k9rAK73iw== + dependencies: + "@types/node" "12.20.24" + colors "~1.2.1" + fs-extra "~7.0.1" + import-lazy "~4.0.0" + jju "~1.4.0" + resolve "~1.17.0" + semver "~7.3.0" + timsort "~0.3.0" + z-schema "~5.0.2" + "@rushstack/rig-package@0.3.7": version "0.3.7" resolved "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.3.7.tgz#3fa564b1d129d28689dd4309502792b15e84bf81" From e80ecad93c3b3dd3cebd7a293a72bb52b98d91d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Mon, 11 Apr 2022 13:42:15 +0200 Subject: [PATCH 41/58] bump all MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/clever-pumpkins-tease.md | 5 ++ package.json | 8 +- packages/cli/package.json | 2 +- yarn.lock | 113 ++++++++-------------------- 4 files changed, 40 insertions(+), 88 deletions(-) create mode 100644 .changeset/clever-pumpkins-tease.md diff --git a/.changeset/clever-pumpkins-tease.md b/.changeset/clever-pumpkins-tease.md new file mode 100644 index 0000000000..d0784361ff --- /dev/null +++ b/.changeset/clever-pumpkins-tease.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Bump the `rushstack` api generator libraries to their latest versions diff --git a/package.json b/package.json index dc72b8974b..6fea4e081a 100644 --- a/package.json +++ b/package.json @@ -52,10 +52,10 @@ "version": "1.1.0-next.2", "dependencies": { "@manypkg/get-packages": "^1.1.3", - "@microsoft/api-documenter": "^7.17.0", - "@microsoft/api-extractor": "^7.19.4", - "@microsoft/api-extractor-model": "^7.16.0", - "@microsoft/tsdoc": "^0.13.2" + "@microsoft/api-documenter": "^7.17.5", + "@microsoft/api-extractor": "^7.21.2", + "@microsoft/api-extractor-model": "^7.16.1", + "@microsoft/tsdoc": "^0.14.1" }, "devDependencies": { "@changesets/cli": "^2.14.0", diff --git a/packages/cli/package.json b/packages/cli/package.json index e362caf40e..c9818e48b7 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -153,7 +153,7 @@ "ts-node": "^10.0.0" }, "peerDependencies": { - "@microsoft/api-extractor": "^7.19.2" + "@microsoft/api-extractor": "^7.21.2" }, "peerDependenciesMeta": { "@microsoft/api-extractor": { diff --git a/yarn.lock b/yarn.lock index 9b08e78fe5..76e6ada9c1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4347,38 +4347,20 @@ dependencies: "@types/gapi.client" "*" -"@microsoft/api-documenter@^7.17.0": - version "7.17.0" - resolved "https://registry.npmjs.org/@microsoft/api-documenter/-/api-documenter-7.17.0.tgz#7d2b7775b37775fc7491b94cb5fa13ee8271fcc3" - integrity sha512-rIZcfDkBsWsflvN1n0tVgIUdivV7slBIsN0WyK8gUG1MjK7dv+rbAB5QPLhg3dPvbXLgPLanJCFwoO2yFdxs+A== +"@microsoft/api-documenter@^7.17.5": + version "7.17.5" + resolved "https://registry.npmjs.org/@microsoft/api-documenter/-/api-documenter-7.17.5.tgz#cdaec54ad04d66b6f4c6f797f4120ff8c844a82d" + integrity sha512-zyJS3qORQP33S8EU0YPZb/JLIbMoslzj1bg8VmgfYCnxhX+3/FmlrTqDCwA9h2TR4bu1r7aQ26AfjUbBUz9+EA== dependencies: - "@microsoft/api-extractor-model" "7.16.0" + "@microsoft/api-extractor-model" "7.16.1" "@microsoft/tsdoc" "0.13.2" - "@rushstack/node-core-library" "3.45.1" - "@rushstack/ts-command-line" "4.10.7" + "@rushstack/node-core-library" "3.45.2" + "@rushstack/ts-command-line" "4.10.8" colors "~1.2.1" js-yaml "~3.13.1" resolve "~1.17.0" -"@microsoft/api-extractor-model@7.15.3": - version "7.15.3" - resolved "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.15.3.tgz#cf76deeeb2733d974da678f530c2dbaceb18a065" - integrity sha512-NkSjolmSI7NGvbdz0Y7kjQfdpD+j9E5CwXTxEyjDqxd10MI7GXV8DnAsQ57GFJcgHKgTjf2aUnYfMJ9w3aMicw== - dependencies: - "@microsoft/tsdoc" "0.13.2" - "@microsoft/tsdoc-config" "~0.15.2" - "@rushstack/node-core-library" "3.45.0" - -"@microsoft/api-extractor-model@7.16.0": - version "7.16.0" - resolved "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.16.0.tgz#3db7360897115f26a857f1f684fb5af82b0ef9f6" - integrity sha512-0FOrbNIny8mzBrzQnSIkEjAXk0JMSnPmWYxt3ZDTPVg9S8xIPzB6lfgTg9+Mimu0RKCpGKBpd+v2WcR5vGzyUQ== - dependencies: - "@microsoft/tsdoc" "0.13.2" - "@microsoft/tsdoc-config" "~0.15.2" - "@rushstack/node-core-library" "3.45.1" - -"@microsoft/api-extractor-model@^7.16.0": +"@microsoft/api-extractor-model@7.16.1", "@microsoft/api-extractor-model@^7.16.1": version "7.16.1" resolved "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.16.1.tgz#f6e53614e90c8a6be47bad5b91d49cc6d8c5c2bf" integrity sha512-+1mlvy/ji+mUuH7WdVZ6fTo/aCKfS6m37aAFVOFWLfkMvmR+I9SjPfiv9qOg83If7GOrk2HPiHHibv6kA80VTg== @@ -4387,17 +4369,17 @@ "@microsoft/tsdoc-config" "~0.15.2" "@rushstack/node-core-library" "3.45.2" -"@microsoft/api-extractor@^7.19.4": - version "7.19.4" - resolved "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.19.4.tgz#95d43d410a1dfb28a02062c4693bcb9c52afe9eb" - integrity sha512-iehC6YA3DGJvxTUaK7HUtQmP6hAQU07+Q/OR8TG4dVR6KpqCi9UPEVk8AgCvQkiK+6FbVEFQTx0qLuYk4EeuHg== +"@microsoft/api-extractor@^7.21.2": + version "7.21.2" + resolved "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.21.2.tgz#0f524e7e1cf7b000924772fb8f6b5f60cf42fba8" + integrity sha512-m0+YPaXVou01O/V9swugZG7Gn4mw6HSWY+uisf0j2JPRZcoEDyoYe4hg0ERKXOEf0hByOnMLT28nQ82v8ig9Yw== dependencies: - "@microsoft/api-extractor-model" "7.15.3" + "@microsoft/api-extractor-model" "7.16.1" "@microsoft/tsdoc" "0.13.2" "@microsoft/tsdoc-config" "~0.15.2" - "@rushstack/node-core-library" "3.45.0" - "@rushstack/rig-package" "0.3.7" - "@rushstack/ts-command-line" "4.10.6" + "@rushstack/node-core-library" "3.45.2" + "@rushstack/rig-package" "0.3.9" + "@rushstack/ts-command-line" "4.10.8" colors "~1.2.1" lodash "~4.17.15" resolve "~1.17.0" @@ -4425,11 +4407,16 @@ jju "~1.4.0" resolve "~1.19.0" -"@microsoft/tsdoc@0.13.2", "@microsoft/tsdoc@^0.13.2": +"@microsoft/tsdoc@0.13.2": version "0.13.2" resolved "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.13.2.tgz#3b0efb6d3903bd49edb073696f60e90df08efb26" integrity sha512-WrHvO8PDL8wd8T2+zBGKrMwVL5IyzR3ryWUsl0PXgEV0QHup4mTLi0QcATefGI6Gx9Anu7vthPyyyLpY0EpiQg== +"@microsoft/tsdoc@^0.14.1": + version "0.14.1" + resolved "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.14.1.tgz#155ef21065427901994e765da8a0ba0eaae8b8bd" + integrity sha512-6Wci+Tp3CgPt/B9B0a3J4s3yMgLNSku6w5TV6mN+61C71UqsRBv2FUibBf3tPGlNxebgPHMEUzKpb1ggE8KCKw== + "@mswjs/cookies@^0.1.6", "@mswjs/cookies@^0.1.7": version "0.1.7" resolved "https://registry.npmjs.org/@mswjs/cookies/-/cookies-0.1.7.tgz#d334081b2c51057a61c1dd7b76ca3cac02251651" @@ -5249,36 +5236,6 @@ estree-walker "^2.0.1" picomatch "^2.2.2" -"@rushstack/node-core-library@3.45.0": - version "3.45.0" - resolved "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.45.0.tgz#8c86b39271b6d84260b1e70db87e1e265b54f620" - integrity sha512-YMuIJl19vQT1+g/OU9mLY6T5ZBT9uDlmeXExDQACpGuxTJW+LHNbk/lRX+eCApQI2eLBlaL4U68r3kZlqwbdmw== - dependencies: - "@types/node" "12.20.24" - colors "~1.2.1" - fs-extra "~7.0.1" - import-lazy "~4.0.0" - jju "~1.4.0" - resolve "~1.17.0" - semver "~7.3.0" - timsort "~0.3.0" - z-schema "~5.0.2" - -"@rushstack/node-core-library@3.45.1": - version "3.45.1" - resolved "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.45.1.tgz#787361b61a48d616eb4b059641721a3dc138f001" - integrity sha512-BwdssTNe007DNjDBxJgInHg8ePytIPyT0La7ZZSQZF9+rSkT42AygXPGvbGsyFfEntjr4X37zZSJI7yGzL16cQ== - dependencies: - "@types/node" "12.20.24" - colors "~1.2.1" - fs-extra "~7.0.1" - import-lazy "~4.0.0" - jju "~1.4.0" - resolve "~1.17.0" - semver "~7.3.0" - timsort "~0.3.0" - z-schema "~5.0.2" - "@rushstack/node-core-library@3.45.2": version "3.45.2" resolved "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.45.2.tgz#68fc89c5bea4007359fa4ff203bf3eca27037f40" @@ -5294,28 +5251,18 @@ timsort "~0.3.0" z-schema "~5.0.2" -"@rushstack/rig-package@0.3.7": - version "0.3.7" - resolved "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.3.7.tgz#3fa564b1d129d28689dd4309502792b15e84bf81" - integrity sha512-pzMsTSeTC8IiZ6EJLr53gGMvhT4oLWH+hxD7907cHyWuIUlEXFtu/2pK25vUQT13nKp5DJCWxXyYoGRk/h6rtA== +"@rushstack/rig-package@0.3.9": + version "0.3.9" + resolved "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.3.9.tgz#5e10ada5a8348f886b6ebe3eed436492d6ccf70c" + integrity sha512-z3Oxpfb4n9mGXwseX+ifpkmUf9B8Fy8oieVwg8eFgpCbzllkgOwEiwLKEnRWVQ8owFcd46NCKz+7ICH35CRsAw== dependencies: resolve "~1.17.0" strip-json-comments "~3.1.1" -"@rushstack/ts-command-line@4.10.6": - version "4.10.6" - resolved "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.10.6.tgz#5669e481e4339ceb4e1428183eb0937d3bc3841b" - integrity sha512-Y3GkUag39sTIlukDg9mUp8MCHrrlJ27POrBNRQGc/uF+VVgX8M7zMzHch5zP6O1QVquWgD7Engdpn2piPYaS/g== - dependencies: - "@types/argparse" "1.0.38" - argparse "~1.0.9" - colors "~1.2.1" - string-argv "~0.3.1" - -"@rushstack/ts-command-line@4.10.7": - version "4.10.7" - resolved "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.10.7.tgz#21e3757a756cbd4f7eeab8f89ec028a64d980efc" - integrity sha512-CjS+DfNXUSO5Ab2wD1GBGtUTnB02OglRWGqfaTcac9Jn45V5MeUOsq/wA8wEeS5Y/3TZ2P1k+IWdVDiuOFP9Og== +"@rushstack/ts-command-line@4.10.8": + version "4.10.8" + resolved "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.10.8.tgz#f4bec690e7f4838e6f91028d8a557e67c3a75f68" + integrity sha512-G7CQYY/m3aZU5fVxbebv35yDeua7sSumrDAB2pJp0d60ZEsxGkUQW8771CeMcGWwSKqT9PxPzKpmIakiWv54sA== dependencies: "@types/argparse" "1.0.38" argparse "~1.0.9" From ab230a433f02c0a6c1cf92169839fe826bc40a2c Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Mon, 11 Apr 2022 14:19:48 +0200 Subject: [PATCH 42/58] add changesets Signed-off-by: Emma Indal --- .changeset/breezy-mugs-build.md | 5 +++++ .changeset/clever-buckets-doubt.md | 5 +++++ .changeset/rude-bees-rest.md | 5 +++++ .changeset/thirty-sloths-knock.md | 11 +++++++++++ plugins/home/package.json | 1 - 5 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 .changeset/breezy-mugs-build.md create mode 100644 .changeset/clever-buckets-doubt.md create mode 100644 .changeset/rude-bees-rest.md create mode 100644 .changeset/thirty-sloths-knock.md diff --git a/.changeset/breezy-mugs-build.md b/.changeset/breezy-mugs-build.md new file mode 100644 index 0000000000..026932e971 --- /dev/null +++ b/.changeset/breezy-mugs-build.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-home': patch +--- + +Export template logos `TemplateBackstageLogo` and `TemplateBackstageLogoIcon` from package. diff --git a/.changeset/clever-buckets-doubt.md b/.changeset/clever-buckets-doubt.md new file mode 100644 index 0000000000..751db72bf8 --- /dev/null +++ b/.changeset/clever-buckets-doubt.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs': patch +--- + +imports from `@backstage/plugin-search-react` instead of `@backstage/plugin-search` diff --git a/.changeset/rude-bees-rest.md b/.changeset/rude-bees-rest.md new file mode 100644 index 0000000000..793b130b35 --- /dev/null +++ b/.changeset/rude-bees-rest.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-search-react': patch +--- + +New search package to hold things the search plugin itself and other frontend plugins (e.g. techdocs, home) depend on. diff --git a/.changeset/thirty-sloths-knock.md b/.changeset/thirty-sloths-knock.md new file mode 100644 index 0000000000..1ad559e368 --- /dev/null +++ b/.changeset/thirty-sloths-knock.md @@ -0,0 +1,11 @@ +--- +'@backstage/plugin-search': patch +--- + +The following exports has been moved to `@backstage/plugin-search-react` and will be removed in the next release. import from `@backstage/plugin-search-react` instead. + +- `SearchApi` interface. +- `searchApiRef` +- `SearchContext` +- `SearchContextProvider` +- `useSearch` diff --git a/plugins/home/package.json b/plugins/home/package.json index e59e7a39bb..aac39c397a 100644 --- a/plugins/home/package.json +++ b/plugins/home/package.json @@ -38,7 +38,6 @@ "@backstage/core-components": "^0.9.3-next.1", "@backstage/core-plugin-api": "^1.0.0", "@backstage/plugin-catalog-react": "^1.0.1-next.2", - "@backstage/plugin-search-react": "^0.0.0", "@backstage/plugin-stack-overflow": "^0.1.0-next.0", "@backstage/theme": "^0.2.15", "@backstage/config": "^1.0.0", From f3a72b172a2e79eb9caf335aaa9cdc0c44e7cf9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Mon, 11 Apr 2022 14:57:12 +0200 Subject: [PATCH 43/58] bump moment to fix vulnerability MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index b9cf5fdd60..4a252715d5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18118,9 +18118,9 @@ moment-timezone@^0.5.x: moment ">= 2.9.0" "moment@>= 2.9.0", moment@>=2.14.0, moment@^2.27.0, moment@^2.29.1: - version "2.29.1" - resolved "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3" - integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ== + version "2.29.2" + resolved "https://registry.npmjs.org/moment/-/moment-2.29.2.tgz#00910c60b20843bcba52d37d58c628b47b1f20e4" + integrity sha512-UgzG4rvxYpN15jgCmVJwac49h9ly9NurikMWGPdVxm8GZD6XjkKPxDTjQQ43gtGgnV3X0cAyWDdP2Wexoquifg== morgan@^1.10.0: version "1.10.0" From f4cdf4cac1a8f9c1f86efb0cc66f907758b1d66d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Mon, 11 Apr 2022 15:06:35 +0200 Subject: [PATCH 44/58] Defensively encode URL parameters when fetching ELB keys MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/ninety-islands-report.md | 5 +++++ plugins/auth-backend/src/providers/aws-alb/provider.ts | 6 ++++-- 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 .changeset/ninety-islands-report.md diff --git a/.changeset/ninety-islands-report.md b/.changeset/ninety-islands-report.md new file mode 100644 index 0000000000..4a515b75cd --- /dev/null +++ b/.changeset/ninety-islands-report.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend': patch +--- + +Defensively encode URL parameters when fetching ELB keys diff --git a/plugins/auth-backend/src/providers/aws-alb/provider.ts b/plugins/auth-backend/src/providers/aws-alb/provider.ts index 12f7c7f4b4..5206dc125c 100644 --- a/plugins/auth-backend/src/providers/aws-alb/provider.ts +++ b/plugins/auth-backend/src/providers/aws-alb/provider.ts @@ -211,8 +211,10 @@ export class AwsAlbAuthProvider implements AuthProviderRouteHandlers { if (optionalCacheKey) { return crypto.createPublicKey(optionalCacheKey); } - const keyText: string = await fetch( - `https://public-keys.auth.elb.${this.region}.amazonaws.com/${keyId}`, + const keyText = await fetch( + `https://public-keys.auth.elb.${encodeURIComponent( + this.region, + )}.amazonaws.com/${encodeURIComponent(keyId)}`, ).then(response => response.text()); const keyValue = crypto.createPublicKey(keyText); this.keyCache.set(keyId, keyValue.export({ format: 'pem', type: 'spki' })); From 612810586b4c62538c642ca36000bbf07b4c90fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Mon, 11 Apr 2022 15:15:10 +0200 Subject: [PATCH 45/58] bump ansi-regex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index b9cf5fdd60..b61448cad9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7551,9 +7551,9 @@ ansi-regex@^2.0.0: integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + version "3.0.1" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1" + integrity sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw== ansi-regex@^4.1.0: version "4.1.0" From f8b0197fc2aaa8d5e780f0199a11654218fe3e64 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 11 Apr 2022 15:18:21 +0200 Subject: [PATCH 46/58] docs: add section to help decide where to place code Signed-off-by: Patrik Oldsberg --- .../package-decision.drawio.svg | 269 ++++++++++++++++++ docs/overview/architecture-overview.md | 12 + 2 files changed, 281 insertions(+) create mode 100644 docs/assets/architecture-overview/package-decision.drawio.svg diff --git a/docs/assets/architecture-overview/package-decision.drawio.svg b/docs/assets/architecture-overview/package-decision.drawio.svg new file mode 100644 index 0000000000..e5199adf3f --- /dev/null +++ b/docs/assets/architecture-overview/package-decision.drawio.svg @@ -0,0 +1,269 @@ + + + + + + + + + +
+
+
+ No +
+
+
+
+ + No + +
+
+ + + + + +
+
+
+ Yes +
+
+
+
+ + Yes + +
+
+ + + + +
+
+
+ Is the new addition public API? +
+ i.e. exported from the package +
+
+
+
+ + Is the new addition public API?... + +
+
+ + + + + + +
+
+
+ In what plugin package should I put my code? +
+
+
+
+ + In what plugin package sho... + +
+
+ + + + +
+
+
+ Put it in the package +
+ that uses it +
+
+
+
+ + Put it in the package... + +
+
+ + + + + +
+
+
+ Only app/backend +
+
+
+
+ + Only app/backend + +
+
+ + + + + + +
+
+
+ Is the export supposed +
+ to be used by other plugins or just app/backend packages? +
+
+
+
+ + Is the export supposed... + +
+
+ + + + +
+
+
+ Put it in the frontend or backend plugin package +
+
+
+
+ + Put it in the frontend or... + +
+
+ + + + + +
+
+
+ No +
+
+
+
+ + No + +
+
+ + + + + +
+
+
+ Yes +
+
+
+
+ + Yes + +
+
+ + + + +
+
+
+ Should the export be +
+ usable by both Node.js and browser packages? +
+
+
+
+ + Should the export be... + +
+
+ + + +
+
+
+ Yes, used by other plugins +
+
+
+
+ + Yes, used by other plugins + +
+
+ + + + +
+
+
+ Put frontend exports in <plugin>-react, and backend exports in <plugin>-node +
+
+
+
+ + Put frontend exports in <p... + +
+
+ + + + +
+
+
+ Add it to <plugin>-common, but be sure to support both Node.js and web environments +
+
+
+
+ + Add it to <plugin>-common, but be... + +
+
+ +
+ + + + + Viewer does not support full SVG 1.1 + + + +
diff --git a/docs/overview/architecture-overview.md b/docs/overview/architecture-overview.md index 5b6b81cf10..382399e603 100644 --- a/docs/overview/architecture-overview.md +++ b/docs/overview/architecture-overview.md @@ -256,6 +256,18 @@ The Backstage CLI is in a category of its own and is depended on by virtually all other packages. It's not a library in itself though, and must always be a development dependency only. +### Deciding where you place your code + +It can sometimes be difficult to decide where to place your plugin code. For example +should it go directly in the `-backend` plugin package or in the `-node` package? +As a rule of thumb you should try to keep the exposure of your code as low +as possible. If it doesn't need to be public API, it's best to avoid. If you don't +need it to be used by other plugins, then keep it directly in the plugin packages. + +Below is a chart to help you decide where to place your code. + +![Package decision](../assets/architecture-overview/package-decision.drawio.svg) + ## Databases As we have seen, both the `lighthouse-audit-service` and `catalog-backend` From 43759dd789e0bf750fb939cf864a96a048731de2 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Mon, 11 Apr 2022 15:43:43 +0200 Subject: [PATCH 47/58] create-app: Remove octokit/rest from dependencies section Signed-off-by: Johan Haals --- .changeset/light-dragons-crash.md | 5 +++++ .../templates/default-app/packages/backend/package.json.hbs | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 .changeset/light-dragons-crash.md diff --git a/.changeset/light-dragons-crash.md b/.changeset/light-dragons-crash.md new file mode 100644 index 0000000000..869e590783 --- /dev/null +++ b/.changeset/light-dragons-crash.md @@ -0,0 +1,5 @@ +--- +'@backstage/create-app': patch +--- + +Remove `@octokit/rest` from dependencies. diff --git a/packages/create-app/templates/default-app/packages/backend/package.json.hbs b/packages/create-app/templates/default-app/packages/backend/package.json.hbs index b91366dee8..5b5e865541 100644 --- a/packages/create-app/templates/default-app/packages/backend/package.json.hbs +++ b/packages/create-app/templates/default-app/packages/backend/package.json.hbs @@ -36,7 +36,6 @@ "@backstage/plugin-search-backend-node": "^{{version '@backstage/plugin-search-backend-node'}}", "@backstage/plugin-techdocs-backend": "^{{version '@backstage/plugin-techdocs-backend'}}", "@gitbeaker/node": "^34.6.0", - "@octokit/rest": "^18.5.3", "dockerode": "^3.3.1", "express": "^4.17.1", "express-promise-router": "^4.1.0", From 47f0af3410774b8a4b7288f1fb21aa78a528e2c1 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Mon, 11 Apr 2022 16:11:44 +0200 Subject: [PATCH 48/58] remove gitbeaker node, update changeset Signed-off-by: Johan Haals --- .changeset/light-dragons-crash.md | 10 +++++++++- .../default-app/packages/backend/package.json.hbs | 1 - 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.changeset/light-dragons-crash.md b/.changeset/light-dragons-crash.md index 869e590783..35dea73ae6 100644 --- a/.changeset/light-dragons-crash.md +++ b/.changeset/light-dragons-crash.md @@ -2,4 +2,12 @@ '@backstage/create-app': patch --- -Remove `@octokit/rest` from dependencies. +Removed `@octokit/rest` and `@gitbeaker/node` from backend dependencies as these are unused in the default app. + +To apply these changes to your existing app, remove the following lines from the `dependencies` section of `packages/backend/package.json` + +```diff + "@backstage/plugin-techdocs-backend": "^1.0.0", +- "@gitbeaker/node": "^34.6.0", +- "@octokit/rest": "^18.5.3", +``` diff --git a/packages/create-app/templates/default-app/packages/backend/package.json.hbs b/packages/create-app/templates/default-app/packages/backend/package.json.hbs index 5b5e865541..939b13bf86 100644 --- a/packages/create-app/templates/default-app/packages/backend/package.json.hbs +++ b/packages/create-app/templates/default-app/packages/backend/package.json.hbs @@ -35,7 +35,6 @@ {{/if}} "@backstage/plugin-search-backend-node": "^{{version '@backstage/plugin-search-backend-node'}}", "@backstage/plugin-techdocs-backend": "^{{version '@backstage/plugin-techdocs-backend'}}", - "@gitbeaker/node": "^34.6.0", "dockerode": "^3.3.1", "express": "^4.17.1", "express-promise-router": "^4.1.0", From 0504eec0d67d3a988a34056b080a3c7e184d6e0a Mon Sep 17 00:00:00 2001 From: Luna Stadler Date: Mon, 11 Apr 2022 16:02:59 +0200 Subject: [PATCH 49/58] Add Spread Group to adopters Signed-off-by: Luna Stadler --- ADOPTERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ADOPTERS.md b/ADOPTERS.md index f6529e505c..1a1c3686d4 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -112,3 +112,4 @@ _If you're using Backstage in your organization, please try to add your company | [Wistia](https://wistia.com/) | [@qrush](https://github.com/qrush), [@okize](https://github.com/okize) | Internal Developer Portal, service catalog, tech docs and more | | [SIX](https://www.six-group.com/) | [@jbadeau](https://github.com/jbadeau), [@tomassatka](https://github.com/tomassatka) | Internal DevOps portal hosting our software and dataset catalog, as well as custom plugins for observability, service virtualization, deployments, incident managment and quality metrics. | | [Raiffeisen Bank International](https://www.rbinternational.com/) | [Daniel Baumgartner](https://github.com/dabarbi) | From developers for developers: software catalog, techdocs and heavy use of scaffolder to drive reuse on engineering level forward. Part of inner source initiative. Multi national setup coming. | +| [Spread Group](https://www.spreadgroup.com/) | [Luna Stadler](https://github.com/heyLu), [Iván González](https://github.com/ivangonzalezacuna) | Internal Developer Portal, an overview of all running software, architecture documentation and more; replacing and unifying a variety of internal tools. | From b7d035cc29ea5db46fe36f5fd4799cdbaa849c18 Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Mon, 11 Apr 2022 16:40:47 +0200 Subject: [PATCH 50/58] feedback fixups Signed-off-by: Emma Indal --- .changeset/rude-bees-rest.md | 2 +- plugins/home/api-report.md | 8 +++---- .../home/src/assets/TemplateBackstageLogo.tsx | 6 ++++- plugins/search-react/README.md | 4 +++- plugins/search-react/api-report.md | 9 +++----- plugins/search-react/package.json | 4 ++-- .../src/context/SearchContext.tsx | 5 +++- plugins/search-react/src/index.ts | 11 +++++++-- plugins/search/api-report.md | 3 --- plugins/search/src/apis.ts | 4 ++-- .../SearchContext/SearchContext.tsx | 4 ++-- yarn.lock | 23 ------------------- 12 files changed, 35 insertions(+), 48 deletions(-) diff --git a/.changeset/rude-bees-rest.md b/.changeset/rude-bees-rest.md index 793b130b35..7ca4e7492c 100644 --- a/.changeset/rude-bees-rest.md +++ b/.changeset/rude-bees-rest.md @@ -1,5 +1,5 @@ --- -'@backstage/plugin-search-react': patch +'@backstage/plugin-search-react': minor --- New search package to hold things the search plugin itself and other frontend plugins (e.g. techdocs, home) depend on. diff --git a/plugins/home/api-report.md b/plugins/home/api-report.md index 21c5592636..a65f8cda5c 100644 --- a/plugins/home/api-report.md +++ b/plugins/home/api-report.md @@ -119,12 +119,13 @@ export const SettingsModal: (props: { children: JSX.Element; }) => JSX.Element; +// Warning: (ae-forgotten-export) The symbol "TemplateBackstageLogoProps" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "TemplateBackstageLogo" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const TemplateBackstageLogo: (props: { - classes: Classes; -}) => JSX.Element; +export const TemplateBackstageLogo: ( + props: TemplateBackstageLogoProps, +) => JSX.Element; // Warning: (ae-missing-release-tag) "TemplateBackstageLogoIcon" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -136,7 +137,6 @@ export const WelcomeTitle: () => JSX.Element; // Warnings were encountered during analysis: // -// src/assets/TemplateBackstageLogo.d.ts:7:5 - (ae-forgotten-export) The symbol "Classes" needs to be exported by the entry point index.d.ts // src/extensions.d.ts:6:5 - (ae-forgotten-export) The symbol "RendererProps" needs to be exported by the entry point index.d.ts // src/extensions.d.ts:27:5 - (ae-forgotten-export) The symbol "ComponentParts" needs to be exported by the entry point index.d.ts ``` diff --git a/plugins/home/src/assets/TemplateBackstageLogo.tsx b/plugins/home/src/assets/TemplateBackstageLogo.tsx index 0fc908ee39..9088cfa58c 100644 --- a/plugins/home/src/assets/TemplateBackstageLogo.tsx +++ b/plugins/home/src/assets/TemplateBackstageLogo.tsx @@ -21,7 +21,11 @@ type Classes = { path: string; }; -export const TemplateBackstageLogo = (props: { classes: Classes }) => { +type TemplateBackstageLogoProps = { + classes: Classes; +}; + +export const TemplateBackstageLogo = (props: TemplateBackstageLogoProps) => { return ( ; -// Warning: (ae-forgotten-export) The symbol "SearchContextValue" needs to be exported by the entry point index.d.ts -// -// @public (undocumented) -export const SearchContext: React_2.Context; - // @public (undocumented) export const SearchContextProvider: ({ initialState, @@ -49,7 +44,7 @@ export const SearchContextProviderForStorybook: ( props: ComponentProps & QueryResultProps, ) => JSX.Element; -// @public +// @public (undocumented) export type SearchContextState = { term: string; types: string[]; @@ -57,6 +52,8 @@ export type SearchContextState = { pageCursor?: string; }; +// Warning: (ae-forgotten-export) The symbol "SearchContextValue" needs to be exported by the entry point index.d.ts +// // @public (undocumented) export const useSearch: () => SearchContextValue; diff --git a/plugins/search-react/package.json b/plugins/search-react/package.json index 15251b4ac7..151660943e 100644 --- a/plugins/search-react/package.json +++ b/plugins/search-react/package.json @@ -44,8 +44,8 @@ "devDependencies": { "@backstage/test-utils": "^1.0.1-next.1", "@testing-library/react": "^12.1.3", - "@testing-library/react-hooks": "^8.0.0", - "@testing-library/jest-dom": "^5.16.4" + "@testing-library/react-hooks": "^7.0.2", + "@testing-library/jest-dom": "^5.10.1" }, "files": [ "dist" diff --git a/plugins/search-react/src/context/SearchContext.tsx b/plugins/search-react/src/context/SearchContext.tsx index 217c94cca2..d6245d5ccf 100644 --- a/plugins/search-react/src/context/SearchContext.tsx +++ b/plugins/search-react/src/context/SearchContext.tsx @@ -40,7 +40,6 @@ type SearchContextValue = { } & SearchContextState; /** - * The initial state of `SearchContextProvider`. * * @public */ @@ -58,6 +57,10 @@ export const SearchContext = createContext( undefined, ); +/** + * The initial state of `SearchContextProvider`. + * + */ const searchInitialState: SearchContextState = { term: '', pageCursor: undefined, diff --git a/plugins/search-react/src/index.ts b/plugins/search-react/src/index.ts index 498e4d6ce3..934cf2e9f1 100644 --- a/plugins/search-react/src/index.ts +++ b/plugins/search-react/src/index.ts @@ -14,5 +14,12 @@ * limitations under the License. */ -export * from './api'; -export * from './context'; +export { searchApiRef } from './api'; +export type { SearchApi } from './api'; +export { + SearchContextProvider, + useSearch, + SearchContextProviderForStorybook, + SearchApiProviderForStorybook, +} from './context'; +export type { SearchContextState } from './context'; diff --git a/plugins/search/api-report.md b/plugins/search/api-report.md index f524652f51..d85158c925 100644 --- a/plugins/search/api-report.md +++ b/plugins/search/api-report.md @@ -81,7 +81,6 @@ export type HomePageSearchBarProps = Partial< // @public (undocumented) export const Router: () => JSX.Element; -// Warning: (tsdoc-at-sign-in-word) The "@" character looks like part of a TSDoc tag; use a backslash to escape it // Warning: (ae-missing-release-tag) "SearchApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public @deprecated (undocumented) @@ -90,7 +89,6 @@ export interface SearchApi { query(query: SearchQuery): Promise; } -// Warning: (tsdoc-at-sign-in-word) The "@" character looks like part of a TSDoc tag; use a backslash to escape it // Warning: (ae-missing-release-tag) "searchApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public @deprecated (undocumented) @@ -140,7 +138,6 @@ export const SearchBarNext: ({ // @public export type SearchBarProps = Partial; -// Warning: (tsdoc-at-sign-in-word) The "@" character looks like part of a TSDoc tag; use a backslash to escape it // Warning: (ae-missing-release-tag) "SearchContextProvider" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public @deprecated (undocumented) diff --git a/plugins/search/src/apis.ts b/plugins/search/src/apis.ts index 62f65dbe4a..096b11bb5e 100644 --- a/plugins/search/src/apis.ts +++ b/plugins/search/src/apis.ts @@ -25,14 +25,14 @@ import { SearchQuery, SearchResultSet } from '@backstage/plugin-search-common'; import qs from 'qs'; /** - * @deprecated import from "@backstage/plugin-search-react" instead + * @deprecated import from `@backstage/plugin-search-react` instead */ export const searchApiRef = createApiRef({ id: 'plugin.search.queryservice', }); /** - * @deprecated import from "@backstage/plugin-search-react" instead + * @deprecated import from `@backstage/plugin-search-react` instead */ export interface SearchApi { query(query: SearchQuery): Promise; diff --git a/plugins/search/src/components/SearchContext/SearchContext.tsx b/plugins/search/src/components/SearchContext/SearchContext.tsx index d52e43af88..c87295ab99 100644 --- a/plugins/search/src/components/SearchContext/SearchContext.tsx +++ b/plugins/search/src/components/SearchContext/SearchContext.tsx @@ -52,7 +52,7 @@ export type SearchContextState = { }; /** - * @deprecated import from "@backstage/plugin-search-react" instead + * @deprecated import from `@backstage/plugin-search-react` instead */ export const SearchContext = createContext( undefined, @@ -66,7 +66,7 @@ const searchInitialState: SearchContextState = { }; /** - * @deprecated import from "@backstage/plugin-search-react" instead + * @deprecated import from `@backstage/plugin-search-react` instead */ export const SearchContextProvider = ({ initialState = searchInitialState, diff --git a/yarn.lock b/yarn.lock index 223c451347..076b9f222a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5560,21 +5560,6 @@ lodash "^4.17.15" redent "^3.0.0" -"@testing-library/jest-dom@^5.16.4": - version "5.16.4" - resolved "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.4.tgz#938302d7b8b483963a3ae821f1c0808f872245cd" - integrity sha512-Gy+IoFutbMQcky0k+bqqumXZ1cTGswLsFqmNLzNdSKkU9KGV2u9oXhukCbbJ9/LRPKiqwxEE8VpV/+YZlfkPUA== - dependencies: - "@babel/runtime" "^7.9.2" - "@types/testing-library__jest-dom" "^5.9.1" - aria-query "^5.0.0" - chalk "^3.0.0" - css "^3.0.0" - css.escape "^1.5.1" - dom-accessibility-api "^0.5.6" - lodash "^4.17.15" - redent "^3.0.0" - "@testing-library/react-hooks@^7.0.2": version "7.0.2" resolved "https://registry.npmjs.org/@testing-library/react-hooks/-/react-hooks-7.0.2.tgz#3388d07f562d91e7f2431a4a21b5186062ecfee0" @@ -5586,14 +5571,6 @@ "@types/react-test-renderer" ">=16.9.0" react-error-boundary "^3.1.0" -"@testing-library/react-hooks@^8.0.0": - version "8.0.0" - resolved "https://registry.npmjs.org/@testing-library/react-hooks/-/react-hooks-8.0.0.tgz#7d0164bffce4647f506039de0a97f6fcbd20f4bf" - integrity sha512-uZqcgtcUUtw7Z9N32W13qQhVAD+Xki2hxbTR461MKax8T6Jr8nsUvZB+vcBTkzY2nFvsUet434CsgF0ncW2yFw== - dependencies: - "@babel/runtime" "^7.12.5" - react-error-boundary "^3.1.0" - "@testing-library/react@^12.1.3": version "12.1.4" resolved "https://registry.npmjs.org/@testing-library/react/-/react-12.1.4.tgz#09674b117e550af713db3f4ec4c0942aa8bbf2c0" From cc41a55cec6c86b101af4215b56b288a5634fec3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Apr 2022 05:48:59 +0000 Subject: [PATCH 51/58] build(deps): bump @microsoft/microsoft-graph-types from 2.16.0 to 2.18.0 Bumps [@microsoft/microsoft-graph-types](https://github.com/microsoftgraph/msgraph-typescript-typings) from 2.16.0 to 2.18.0. - [Release notes](https://github.com/microsoftgraph/msgraph-typescript-typings/releases) - [Commits](https://github.com/microsoftgraph/msgraph-typescript-typings/compare/2.16.0...2.18.0) --- updated-dependencies: - dependency-name: "@microsoft/microsoft-graph-types" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 46db212a0d..b9222f3014 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4402,9 +4402,9 @@ integrity sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA== "@microsoft/microsoft-graph-types@^2.6.0": - version "2.16.0" - resolved "https://registry.npmjs.org/@microsoft/microsoft-graph-types/-/microsoft-graph-types-2.16.0.tgz#5329890d230c4fdd9f57f39e26dfade0882c94f3" - integrity sha512-Qvxv9mpXb/F4xlESEkSLjREHj3dAixTkH3LVO6Ct6sllc5RWrQxPxaSGqW9IpcLU6jI49f2XNSGLotVef3Irdg== + version "2.18.0" + resolved "https://registry.npmjs.org/@microsoft/microsoft-graph-types/-/microsoft-graph-types-2.18.0.tgz#b2ebdd55c149dfc11cca41cbf1f2082a56242450" + integrity sha512-cWiK0oaz+RrcL6EKfBeoai28L8jWJ1n+nS5cGUgRR4+POk5W5/8DV3Vs3gUNaFwmAqfYrhskyb/SNyytgAC78Q== "@microsoft/tsdoc-config@~0.15.2": version "0.15.2" From 3c26b2edb543abfccdb555b4d1753e60cf4b482a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Apr 2022 05:49:56 +0000 Subject: [PATCH 52/58] build(deps): bump npm-packlist from 3.0.0 to 5.0.0 Bumps [npm-packlist](https://github.com/npm/npm-packlist) from 3.0.0 to 5.0.0. - [Release notes](https://github.com/npm/npm-packlist/releases) - [Changelog](https://github.com/npm/npm-packlist/blob/main/CHANGELOG.md) - [Commits](https://github.com/npm/npm-packlist/compare/v3.0.0...v5.0.0) --- updated-dependencies: - dependency-name: npm-packlist dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .changeset/dependabot-cccf2f0.md | 5 +++++ packages/cli/package.json | 2 +- yarn.lock | 27 ++++++++++++++++++++++----- 3 files changed, 28 insertions(+), 6 deletions(-) create mode 100644 .changeset/dependabot-cccf2f0.md diff --git a/.changeset/dependabot-cccf2f0.md b/.changeset/dependabot-cccf2f0.md new file mode 100644 index 0000000000..6b420f9a48 --- /dev/null +++ b/.changeset/dependabot-cccf2f0.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +build(deps): bump `npm-packlist` from 3.0.0 to 5.0.0 diff --git a/packages/cli/package.json b/packages/cli/package.json index e362caf40e..b793f683db 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -93,7 +93,7 @@ "mini-css-extract-plugin": "^2.4.2", "minimatch": "5.0.1", "node-libs-browser": "^2.2.1", - "npm-packlist": "^3.0.0", + "npm-packlist": "^5.0.0", "ora": "^5.3.0", "postcss": "^8.1.0", "process": "^0.11.10", diff --git a/yarn.lock b/yarn.lock index 46db212a0d..b0ccad00f7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14217,6 +14217,13 @@ ignore-walk@^4.0.1: dependencies: minimatch "^3.0.4" +ignore-walk@^5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/ignore-walk/-/ignore-walk-5.0.1.tgz#5f199e23e1288f518d90358d461387788a154776" + integrity sha512-yemi4pMf51WKT7khInJqAvsIGzoqYXblnsz0ql8tM+yi1EKYTY1evX4NAbJrLL/Aanr2HyZeluqU+Oi7MGHokw== + dependencies: + minimatch "^5.0.1" + ignore@^3.3.5: version "3.3.10" resolved "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" @@ -17932,7 +17939,7 @@ minimatch@3.0.4: dependencies: brace-expansion "^1.1.7" -minimatch@5.0.1, minimatch@^5.0.0: +minimatch@5.0.1, minimatch@^5.0.0, minimatch@^5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== @@ -18592,10 +18599,10 @@ normalize-url@^6.0.1: resolved "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== -npm-bundled@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz#1edd570865a94cdb1bc8220775e29466c9fb234b" - integrity sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA== +npm-bundled@^1.1.1, npm-bundled@^1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz#944c78789bd739035b70baa2ca5cc32b8d860bc1" + integrity sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ== dependencies: npm-normalize-package-bin "^1.0.1" @@ -18654,6 +18661,16 @@ npm-packlist@^3.0.0: npm-bundled "^1.1.1" npm-normalize-package-bin "^1.0.1" +npm-packlist@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/npm-packlist/-/npm-packlist-5.0.0.tgz#74795ebbbf91bd5a2db6ecff4d6fe1f1c1a07e11" + integrity sha512-uU20UwM4Hogfab1Q7htJbhcyafM9lGHxOrDjkKvR2S3z7Ds0uRaESk0cXctczk+ABT4DZWNwjB10xlurFdEwZg== + dependencies: + glob "^7.2.0" + ignore-walk "^5.0.1" + npm-bundled "^1.1.2" + npm-normalize-package-bin "^1.0.1" + npm-pick-manifest@^6.0.0, npm-pick-manifest@^6.1.0, npm-pick-manifest@^6.1.1: version "6.1.1" resolved "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-6.1.1.tgz#7b5484ca2c908565f43b7f27644f36bb816f5148" From bde10e093d4dba1665de5659f45f6e81e5461038 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Apr 2022 05:51:17 +0000 Subject: [PATCH 53/58] build(deps): bump react-hook-form from 7.28.1 to 7.29.0 Bumps [react-hook-form](https://github.com/react-hook-form/react-hook-form) from 7.28.1 to 7.29.0. - [Release notes](https://github.com/react-hook-form/react-hook-form/releases) - [Changelog](https://github.com/react-hook-form/react-hook-form/blob/master/CHANGELOG.md) - [Commits](https://github.com/react-hook-form/react-hook-form/compare/v7.28.1...v7.29.0) --- updated-dependencies: - dependency-name: react-hook-form dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 46db212a0d..ec2f0533bf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -20943,9 +20943,9 @@ react-helmet@6.1.0: react-side-effect "^2.1.0" react-hook-form@^7.12.2, react-hook-form@^7.13.0: - version "7.28.1" - resolved "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.28.1.tgz#95fc37be6c6b9d57212eb7eca055fb36d079b3b7" - integrity sha512-mgwxvXuvt3FMY/mdnWbPc++Zf1U5xYzkhOaL05mtFMLvXc9MvUhMUlKtUVuO12sOrgT3nPXBgVFawtiJ4ONrgg== + version "7.29.0" + resolved "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.29.0.tgz#5e7e41a483b70731720966ed8be52163ea1fecf1" + integrity sha512-NcJqWRF6el5HMW30fqZRt27s+lorvlCCDbTpAyHoodQeYWXgQCvZJJQLC1kRMKdrJknVH0NIg3At6TUzlZJFOQ== react-hot-loader@^4.13.0: version "4.13.0" From 7336fcf2fb7f88c6b3c30c42357feb3f5d112002 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Apr 2022 05:53:14 +0000 Subject: [PATCH 54/58] build(deps): bump @google-cloud/storage from 5.18.3 to 5.19.1 Bumps [@google-cloud/storage](https://github.com/googleapis/nodejs-storage) from 5.18.3 to 5.19.1. - [Release notes](https://github.com/googleapis/nodejs-storage/releases) - [Changelog](https://github.com/googleapis/nodejs-storage/blob/main/CHANGELOG.md) - [Commits](https://github.com/googleapis/nodejs-storage/compare/v5.18.3...v5.19.1) --- updated-dependencies: - dependency-name: "@google-cloud/storage" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- yarn.lock | 42 +++++++++++++++--------------------------- 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/yarn.lock b/yarn.lock index 46db212a0d..6bb92b8ac6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2224,21 +2224,6 @@ qs "^6.10.1" xcase "^2.0.1" -"@google-cloud/common@^3.8.1": - version "3.10.0" - resolved "https://registry.npmjs.org/@google-cloud/common/-/common-3.10.0.tgz#454d1155bb512109cd83c6183aabbd39f9aabda7" - integrity sha512-XMbJYMh/ZSaZnbnrrOFfR/oQrb0SxG4qh6hDisWCoEbFcBHV0qHQo4uXfeMCzolx2Mfkh6VDaOGg+hyJsmxrlw== - dependencies: - "@google-cloud/projectify" "^2.0.0" - "@google-cloud/promisify" "^2.0.0" - arrify "^2.0.1" - duplexify "^4.1.1" - ent "^2.2.0" - extend "^3.0.2" - google-auth-library "^7.14.0" - retry-request "^4.2.2" - teeny-request "^7.0.0" - "@google-cloud/container@^3.0.0": version "3.0.0" resolved "https://registry.npmjs.org/@google-cloud/container/-/container-3.0.0.tgz#b28d086152ac19f22f2574b7e0a39774379fb885" @@ -2275,12 +2260,12 @@ integrity sha512-d4VSA86eL/AFTe5xtyZX+ePUjE8dIFu2T8zmdeNBSa5/kNgXPCx/o/wbFNHAGLJdGnk1vddRuMESD9HbOC8irw== "@google-cloud/storage@^5.6.0", "@google-cloud/storage@^5.8.0": - version "5.18.3" - resolved "https://registry.npmjs.org/@google-cloud/storage/-/storage-5.18.3.tgz#becacb909b2abf4bb54500a0efd65ceb51ef8eab" - integrity sha512-573qJ0ECoy3nkY5YaMWcVf4/46n/zdvfNgAyjaLQywl/eL38uxDhs7YVJd3pcgslaMUwKKsd/eD3St+Pq2iPew== + version "5.19.1" + resolved "https://registry.npmjs.org/@google-cloud/storage/-/storage-5.19.1.tgz#7252c4eb65e6014bf525a76f3af0774caa3a946d" + integrity sha512-bRTf/AD00+lPTamJdpihXC3AFtAnJFWNh/zQAor972VpuATF7u4V1anwWp0V6rKuKE3BwNM+xWxuuW/nAwEgTA== dependencies: - "@google-cloud/common" "^3.8.1" "@google-cloud/paginator" "^3.0.7" + "@google-cloud/projectify" "^2.0.0" "@google-cloud/promisify" "^2.0.0" abort-controller "^3.0.0" arrify "^2.0.0" @@ -2289,17 +2274,20 @@ configstore "^5.0.0" date-and-time "^2.0.0" duplexify "^4.0.0" + ent "^2.2.0" extend "^3.0.2" gaxios "^4.0.0" get-stream "^6.0.0" - google-auth-library "^7.0.0" + google-auth-library "^7.14.1" hash-stream-validation "^0.2.2" mime "^3.0.0" mime-types "^2.0.8" p-limit "^3.0.1" pumpify "^2.0.0" + retry-request "^4.2.2" snakeize "^0.1.0" stream-events "^1.0.4" + teeny-request "^7.1.3" xdg-basedir "^4.0.0" "@graphiql/toolkit@^0.4.3": @@ -13433,7 +13421,7 @@ globby@^7.1.1: pify "^3.0.0" slash "^1.0.0" -google-auth-library@^7.0.0, google-auth-library@^7.14.0, google-auth-library@^7.6.1: +google-auth-library@^7.14.1, google-auth-library@^7.6.1: version "7.14.1" resolved "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.14.1.tgz#e3483034162f24cc71b95c8a55a210008826213c" integrity sha512-5Rk7iLNDFhFeBYc3s8l1CqzbEBcdhwR193RlD4vSNFajIcINKI8W8P0JLmBpwymHqqWbX34pJDQu39cSy/6RsA== @@ -14043,7 +14031,7 @@ http-parser-js@>=0.5.1: resolved "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.3.tgz#01d2709c79d41698bb01d4decc5e9da4e4a033d9" integrity sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg== -http-proxy-agent@^4.0.0, http-proxy-agent@^4.0.1: +http-proxy-agent@^4.0.1: version "4.0.1" resolved "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== @@ -23718,12 +23706,12 @@ tdigest@^0.1.1: react-router-dom "6.0.0-beta.0" react-use "^17.2.4" -teeny-request@^7.0.0: - version "7.0.1" - resolved "https://registry.npmjs.org/teeny-request/-/teeny-request-7.0.1.tgz#bdd41fdffea5f8fbc0d29392cb47bec4f66b2b4c" - integrity sha512-sasJmQ37klOlplL4Ia/786M5YlOcoLGQyq2TE4WHSRupbAuDaQW0PfVxV4MtdBtRJ4ngzS+1qim8zP6Zp35qCw== +teeny-request@^7.1.3: + version "7.2.0" + resolved "https://registry.npmjs.org/teeny-request/-/teeny-request-7.2.0.tgz#41347ece068f08d741e7b86df38a4498208b2633" + integrity sha512-SyY0pek1zWsi0LRVAALem+avzMLc33MKW/JLLakdP4s9+D7+jHcy5x6P+h94g2QNZsAqQNfX5lsbd3WSeJXrrw== dependencies: - http-proxy-agent "^4.0.0" + http-proxy-agent "^5.0.0" https-proxy-agent "^5.0.0" node-fetch "^2.6.1" stream-events "^1.0.5" From 86a7c4bc5c1ae6ad08c597ae40974f68fdba240e Mon Sep 17 00:00:00 2001 From: Shivam bisht Date: Mon, 11 Apr 2022 16:48:04 +0530 Subject: [PATCH 55/58] added input label for GitlabRepoPicker Signed-off-by: Shivam bisht --- .../src/components/fields/RepoUrlPicker/GitlabRepoPicker.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/GitlabRepoPicker.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/GitlabRepoPicker.tsx index 1c63852866..e2052b792f 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/GitlabRepoPicker.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/GitlabRepoPicker.tsx @@ -65,7 +65,8 @@ export const GitlabRepoPicker = (props: { )} - The organization, user or project that this repo will belong to + The organization, groups, subgroups, user, project (also known as + namespaces in gitlab), that this repo will belong to Date: Mon, 11 Apr 2022 16:59:46 +0530 Subject: [PATCH 56/58] added changeset Signed-off-by: Shivam bisht --- .changeset/orange-dragons-brake.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/orange-dragons-brake.md diff --git a/.changeset/orange-dragons-brake.md b/.changeset/orange-dragons-brake.md new file mode 100644 index 0000000000..125dbfb9a2 --- /dev/null +++ b/.changeset/orange-dragons-brake.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +--- + +modified input label for owner field in GitlabRepoPicker From 946af407db29ea4d576fc81bcb8b78d579a9ae99 Mon Sep 17 00:00:00 2001 From: Shivam bisht Date: Mon, 11 Apr 2022 17:36:37 +0530 Subject: [PATCH 57/58] added changeset Signed-off-by: Shivam bisht --- .changeset/few-hotels-approve.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/few-hotels-approve.md diff --git a/.changeset/few-hotels-approve.md b/.changeset/few-hotels-approve.md new file mode 100644 index 0000000000..49ca040ef7 --- /dev/null +++ b/.changeset/few-hotels-approve.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Changed input label for owner field in GitlabRepoPicker From 3a1ab7617cb86d7c4abcb0a5aeb8437df199dbbf Mon Sep 17 00:00:00 2001 From: Shivam bisht Date: Mon, 11 Apr 2022 18:00:08 +0530 Subject: [PATCH 58/58] removed unnecssary changeset file Signed-off-by: Shivam bisht --- .changeset/orange-dragons-brake.md | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 .changeset/orange-dragons-brake.md diff --git a/.changeset/orange-dragons-brake.md b/.changeset/orange-dragons-brake.md deleted file mode 100644 index 125dbfb9a2..0000000000 --- a/.changeset/orange-dragons-brake.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch ---- - -modified input label for owner field in GitlabRepoPicker