From 2ea30b685225b24dbb1128f879c95a8ee0ed6521 Mon Sep 17 00:00:00 2001 From: Max Morton Date: Fri, 11 Nov 2022 10:27:08 -0800 Subject: [PATCH 01/83] Update GitlabUrlReader to support API and Artifact URLs Signed-off-by: Max Morton --- .../src/reading/GitlabUrlReader.test.ts | 82 +++++++++++++++++++ .../src/reading/GitlabUrlReader.ts | 67 ++++++++++++++- 2 files changed, 148 insertions(+), 1 deletion(-) diff --git a/packages/backend-common/src/reading/GitlabUrlReader.test.ts b/packages/backend-common/src/reading/GitlabUrlReader.test.ts index 29ef3f4ce8..d88c6d8fb9 100644 --- a/packages/backend-common/src/reading/GitlabUrlReader.test.ts +++ b/packages/backend-common/src/reading/GitlabUrlReader.test.ts @@ -573,4 +573,86 @@ describe('GitlabUrlReader', () => { ).rejects.toThrow(NotModifiedError); }); }); + + describe('getGitlabFetchUrl', () => { + beforeEach(() => { + worker.use( + rest.get( + '*/api/v4/projects/group%2Fsubgroup%2Fproject', + (_, res, ctx) => res(ctx.status(200), ctx.json({ id: 12345 })), + ), + ); + }); + it('should fall back to getGitLabFileFetchUrl for blob urls', async () => { + await expect( + gitlabProcessor.getGitlabFetchUrl( + 'https://gitlab.com/group/subgroup/project/-/blob/branch/my/path/to/file.yaml', + ), + ).resolves.toEqual( + 'https://gitlab.com/api/v4/projects/12345/repository/files/my%2Fpath%2Fto%2Ffile.yaml/raw?ref=branch', + ); + }); + it('should work for job artifact urls', async () => { + await expect( + gitlabProcessor.getGitlabFetchUrl( + 'https://gitlab.com/group/subgroup/project/-/jobs/artifacts/branch/raw/my/path/to/file.yaml?job=myJob', + ), + ).resolves.toEqual( + 'https://gitlab.com/api/v4/projects/12345/jobs/artifacts/branch/raw/my/path/to/file.yaml?job=myJob', + ); + }); + it('should pass API urls naively', async () => { + const apiUrl = 'https://gitlab.com/api/v4/my/api/path'; + await expect(gitlabProcessor.getGitlabFetchUrl(apiUrl)).resolves.toEqual( + apiUrl, + ); + }); + it('should fail on unfamiliar or non-Gitlab urls', async () => { + await expect( + gitlabProcessor.getGitlabFetchUrl( + 'https://gitlab.com/some/random/endpoint', + ), + ).rejects.toThrow('Please provide full path to yaml file from GitLab'); + }); + }); + + describe('getGitlabArtfiactFetchUrl', () => { + beforeEach(() => { + worker.use( + rest.get( + '*/api/v4/projects/group%2Fsubgroup%2Fproject', + (_, res, ctx) => res(ctx.status(200), ctx.json({ id: 12345 })), + ), + ); + worker.use( + rest.get( + '*/api/v4/projects/groupA%2Fsubgroup%2Fproject', + (_, res, ctx) => res(ctx.status(404)), + ), + ); + }); + it('should reject urls that are not for the job artifacts API', async () => { + await expect( + gitlabProcessor.getGitlabArtifactFetchUrl( + 'https://gitlab.com/some/url', + ), + ).rejects.toThrow('Unable to process url as an GitLab artifact'); + }); + it('should work for job artifact urls', async () => { + await expect( + gitlabProcessor.getGitlabFetchUrl( + 'https://gitlab.com/group/subgroup/project/-/jobs/artifacts/branch/raw/my/path/to/file.yaml?job=myJob', + ), + ).resolves.toEqual( + 'https://gitlab.com/api/v4/projects/12345/jobs/artifacts/branch/raw/my/path/to/file.yaml?job=myJob', + ); + }); + it('errors in mapping the project ID should be captured', async () => { + await expect( + gitlabProcessor.getGitlabFetchUrl( + 'https://gitlab.com/groupA/subgroup/project/-/jobs/artifacts/branch/raw/my/path/to/file.yaml?job=myJob', + ), + ).rejects.toThrow(/^Unable to translate GitLab artifact URL:/); + }); + }); }); diff --git a/packages/backend-common/src/reading/GitlabUrlReader.ts b/packages/backend-common/src/reading/GitlabUrlReader.ts index eaa15a7208..f704901650 100644 --- a/packages/backend-common/src/reading/GitlabUrlReader.ts +++ b/packages/backend-common/src/reading/GitlabUrlReader.ts @@ -73,7 +73,7 @@ export class GitlabUrlReader implements UrlReader { options?: ReadUrlOptions, ): Promise { const { etag, signal } = options ?? {}; - const builtUrl = await getGitLabFileFetchUrl(url, this.integration.config); + const builtUrl = await this.getGitlabFetchUrl(url); let response: Response; try { @@ -256,4 +256,69 @@ export class GitlabUrlReader implements UrlReader { const { host, token } = this.integration.config; return `gitlab{host=${host},authed=${Boolean(token)}}`; } + + async getGitlabFetchUrl(target: string): Promise { + // If the target is a raw API url then trust that no parsing is needed + if (target.includes('/api/v4/')) { + return target; + } + // If the target is for a job artifact then go down that path + if (target.includes('/-/jobs/artifacts/')) { + return this.getGitlabArtifactFetchUrl(target).then(value => + value.toString(), + ); + } + // Default to the old behavior of assuming the url is for a file + return getGitLabFileFetchUrl(target, this.integration.config); + } + + // convert urls of the form: + // https://example.com///-/jobs/artifacts//raw/?job= + // to urls of the form: + // https://example.com/api/v4/projects/:id/jobs/artifacts/:ref_name/raw/*artifact_path?job= + async getGitlabArtifactFetchUrl(target: string): Promise { + const url = new URL(target); + if (!url.pathname.includes('/-/jobs/artifacts/')) { + throw new Error('Unable to process url as an GitLab artifact'); + } + try { + const [namespaceAndProject, ref] = + url.pathname.split('/-/jobs/artifacts/'); + const projectPath = new URL(url); + projectPath.pathname = namespaceAndProject; + const projectId = await this.resolveProjectToId(projectPath); + const relativePath = getGitLabIntegrationRelativePath( + this.integration.config, + ); + url.pathname = `${relativePath}/api/v4/projects/${projectId}/jobs/artifacts/${ref}`; + return url; + } catch (e) { + throw new Error( + `Unable to translate GitLab artifact URL: ${target}, ${e}`, + ); + } + } + + private async resolveProjectToId(pathToProject: URL): Promise { + let project = pathToProject.pathname; + // Check relative path exist and remove it if so + const relativePath = getGitLabIntegrationRelativePath( + this.integration.config, + ); + if (relativePath) { + project = project.replace(relativePath, ''); + } + // Trim an initial / if it exists + project = project.replace(/^\//, ''); + const result = await fetch( + `${ + pathToProject.origin + }${relativePath}/api/v4/projects/${encodeURIComponent(project)}`, + ); + const data = await result.json(); + if (!result.ok) { + throw new Error(`Gitlab error: ${data.error}, ${data.error_description}`); + } + return Number(data.id); + } } From 6b82598bd82e09ff2979e93aed3d77def54881cd Mon Sep 17 00:00:00 2001 From: Max Morton Date: Fri, 11 Nov 2022 11:17:50 -0800 Subject: [PATCH 02/83] Add changeset Signed-off-by: Max Morton --- .changeset/rich-balloons-leave.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/rich-balloons-leave.md diff --git a/.changeset/rich-balloons-leave.md b/.changeset/rich-balloons-leave.md new file mode 100644 index 0000000000..b77524b396 --- /dev/null +++ b/.changeset/rich-balloons-leave.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-common': patch +--- + +Added the ability to understand Job Artifact URLs and raw API URLs to the GitLab integration From b7cda00d33ef431fddc39ff75e421d4b962ff6e0 Mon Sep 17 00:00:00 2001 From: Max Morton Date: Mon, 14 Nov 2022 09:14:23 -0800 Subject: [PATCH 03/83] add api-report Signed-off-by: Max Morton --- packages/backend-common/api-report.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/backend-common/api-report.md b/packages/backend-common/api-report.md index e8dbd8d150..69d94053b3 100644 --- a/packages/backend-common/api-report.md +++ b/packages/backend-common/api-report.md @@ -458,6 +458,10 @@ export class GitlabUrlReader implements UrlReader { // (undocumented) static factory: ReaderFactory; // (undocumented) + getGitlabArtifactFetchUrl(target: string): Promise; + // (undocumented) + getGitlabFetchUrl(target: string): Promise; + // (undocumented) read(url: string): Promise; // (undocumented) readTree(url: string, options?: ReadTreeOptions): Promise; From dd995cdc7250709b549a606ddec59827dd12b68b Mon Sep 17 00:00:00 2001 From: Thorsten Hake Date: Thu, 10 Nov 2022 08:54:11 +0100 Subject: [PATCH 04/83] Adds support for generic $ref resolving in yaml/json documents. This resolves https://github.com/backstage/backstage/issues/14490. Signed-off-by: Thorsten Hake --- .changeset/tender-colts-greet.md | 5 ++ .../catalog-backend-module-openapi/README.md | 19 ++++-- .../package.json | 2 +- .../src/OpenApiRefProcessor.test.ts | 10 +-- .../src/OpenApiRefProcessor.ts | 4 +- .../src/index.ts | 9 ++- .../src/lib/bundle.test.ts | 68 +++++++++++++++++-- .../src/lib/bundle.ts | 18 ++--- ...test.ts => refPlaceholderResolver.test.ts} | 20 +++--- ...rResolver.ts => refPlaceholderResolver.ts} | 6 +- 10 files changed, 119 insertions(+), 42 deletions(-) create mode 100644 .changeset/tender-colts-greet.md rename plugins/catalog-backend-module-openapi/src/{openApiPlaceholderResolver.test.ts => refPlaceholderResolver.test.ts} (70%) rename plugins/catalog-backend-module-openapi/src/{openApiPlaceholderResolver.ts => refPlaceholderResolver.ts} (94%) diff --git a/.changeset/tender-colts-greet.md b/.changeset/tender-colts-greet.md new file mode 100644 index 0000000000..77c1a8f1b5 --- /dev/null +++ b/.changeset/tender-colts-greet.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-openapi': patch +--- + +Enabled support of resolving `$refs` in all kind of yaml documents, not only OpenAPI. This implicitly adds `$ref` resolving support for AsyncAPI specs. Thus, the `openApiPlaceholderResolver` has been renamed to `refPlaceholderResolver`. diff --git a/plugins/catalog-backend-module-openapi/README.md b/plugins/catalog-backend-module-openapi/README.md index f80798e267..68e9c90e05 100644 --- a/plugins/catalog-backend-module-openapi/README.md +++ b/plugins/catalog-backend-module-openapi/README.md @@ -1,8 +1,10 @@ -# Catalog Backend Module for OpenAPI specifications +# Catalog Backend Module to resolve $refs in yaml documents -This is an extension module to the plugin-catalog-backend plugin, providing extensions targeted at OpenAPI specifications. +This is an extension module to the plugin-catalog-backend plugin, providing an extensions to resolve $refs in yamls documents. -With this you can split your OpenAPI definition into multiple files and reference them. They will be bundled, using an UrlReader, during processing and stored as a single specification. +With this you can split your yaml documents into multiple files and reference them. They will be bundled, using an UrlReader, during processing and stored as a single specification. + +This is useful for OpenAPI and AsyncAPI specifications. ## Installation @@ -15,15 +17,18 @@ yarn add --cwd packages/backend @backstage/plugin-catalog-backend-module-openapi ### Adding the plugin to your `packages/backend` -#### **openApiPlaceholderResolver** +#### **refPlaceholderResolver** -The placeholder resolver can be added by importing `openApiPlaceholderResolver` in `src/plugins/catalog.ts` in your `backend` package and adding the following. +The placeholder resolver can be added by importing `refPlaceholderResolver` in `src/plugins/catalog.ts` in your `backend` package and adding the following. ```ts -builder.setPlaceholderResolver('openapi', openApiPlaceholderResolver); +builder.setPlaceholderResolver('openapi', refPlaceholderResolver); +builder.setPlaceholderResolver('asyncapi', refPlaceholderResolver); ``` -This allows you to use the `$openapi` placeholder when referencing your OpenAPI specification. This will then resolve all `$ref` instances in your specification. +This allows you to use the `$openapi` placeholder when referencing your OpenAPI specification and `$asyncapi` when referencing your AsyncAPI specifications. This will then resolve all `$ref` instances in your specification. + +You can also use this resolver for other kind of yaml files to resolve $ref pointer. ```yaml apiVersion: backstage.io/v1alpha1 diff --git a/plugins/catalog-backend-module-openapi/package.json b/plugins/catalog-backend-module-openapi/package.json index 1055b5ea92..616e10b98d 100644 --- a/plugins/catalog-backend-module-openapi/package.json +++ b/plugins/catalog-backend-module-openapi/package.json @@ -32,7 +32,7 @@ "start": "backstage-cli package start" }, "dependencies": { - "@apidevtools/swagger-parser": "^10.1.0", + "@apidevtools/json-schema-ref-parser": "^9.0.6", "@backstage/backend-common": "workspace:^", "@backstage/catalog-model": "workspace:^", "@backstage/config": "workspace:^", diff --git a/plugins/catalog-backend-module-openapi/src/OpenApiRefProcessor.test.ts b/plugins/catalog-backend-module-openapi/src/OpenApiRefProcessor.test.ts index 9f97e621c2..78568fd19f 100644 --- a/plugins/catalog-backend-module-openapi/src/OpenApiRefProcessor.test.ts +++ b/plugins/catalog-backend-module-openapi/src/OpenApiRefProcessor.test.ts @@ -17,13 +17,13 @@ import { getVoidLogger } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; import { LocationSpec } from '@backstage/plugin-catalog-backend'; import { OpenApiRefProcessor } from './OpenApiRefProcessor'; -import { bundleOpenApiSpecification } from './lib'; +import { bundleFileWithRefs } from './lib'; jest.mock('./lib', () => ({ - bundleOpenApiSpecification: jest.fn(), + bundleFileWithRefs: jest.fn(), })); -const bundledSpecification = ''; +const bundled = ''; describe('OpenApiRefProcessor', () => { const mockLocation = (): LocationSpec => ({ @@ -32,7 +32,7 @@ describe('OpenApiRefProcessor', () => { }); beforeEach(() => { - (bundleOpenApiSpecification as any).mockResolvedValue(bundledSpecification); + (bundleFileWithRefs as any).mockResolvedValue(bundled); }); afterEach(() => { @@ -71,7 +71,7 @@ describe('OpenApiRefProcessor', () => { mockLocation(), ); - expect(result.spec?.definition).toEqual(bundledSpecification); + expect(result.spec?.definition).toEqual(bundled); }); it('should ignore other kinds', async () => { diff --git a/plugins/catalog-backend-module-openapi/src/OpenApiRefProcessor.ts b/plugins/catalog-backend-module-openapi/src/OpenApiRefProcessor.ts index f4cffdf48f..6298aea77d 100644 --- a/plugins/catalog-backend-module-openapi/src/OpenApiRefProcessor.ts +++ b/plugins/catalog-backend-module-openapi/src/OpenApiRefProcessor.ts @@ -21,7 +21,7 @@ import { CatalogProcessor, LocationSpec, } from '@backstage/plugin-catalog-backend'; -import { bundleOpenApiSpecification } from './lib'; +import { bundleFileWithRefs } from './lib'; import { Logger } from 'winston'; /** @@ -84,7 +84,7 @@ export class OpenApiRefProcessor implements CatalogProcessor { this.logger.debug(`Bundling OpenAPI specification from ${location.target}`); try { - const bundledSpec = await bundleOpenApiSpecification( + const bundledSpec = await bundleFileWithRefs( definition.toString(), location.target, this.reader.read, diff --git a/plugins/catalog-backend-module-openapi/src/index.ts b/plugins/catalog-backend-module-openapi/src/index.ts index ccd3ced71e..57f3d8806f 100644 --- a/plugins/catalog-backend-module-openapi/src/index.ts +++ b/plugins/catalog-backend-module-openapi/src/index.ts @@ -13,5 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { refPlaceholderResolver } from './refPlaceholderResolver'; + export { OpenApiRefProcessor } from './OpenApiRefProcessor'; -export { openApiPlaceholderResolver } from './openApiPlaceholderResolver'; +export { refPlaceholderResolver } from './refPlaceholderResolver'; +/** + * @public + * @deprecated replaced by refPlaceholderResolver + */ +export const openApiPlaceholderResolver = refPlaceholderResolver; diff --git a/plugins/catalog-backend-module-openapi/src/lib/bundle.test.ts b/plugins/catalog-backend-module-openapi/src/lib/bundle.test.ts index 57ecd54f26..ec77610733 100644 --- a/plugins/catalog-backend-module-openapi/src/lib/bundle.test.ts +++ b/plugins/catalog-backend-module-openapi/src/lib/bundle.test.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { bundleOpenApiSpecification } from './bundle'; +import { bundleFileWithRefs } from './bundle'; const specification = ` openapi: "3.0.0" @@ -70,7 +70,7 @@ paths: type: string `; -describe('bundleOpenApiSpecification', () => { +describe('bundleFileWithRefs', () => { const read = jest.fn(); const resolveUrl = jest.fn(); @@ -81,7 +81,7 @@ describe('bundleOpenApiSpecification', () => { it('should return the bundled specification', async () => { read.mockResolvedValue(list); - const result = await bundleOpenApiSpecification( + const result = await bundleFileWithRefs( specification, 'https://github.com/owner/repo/blob/main/catalog-info.yaml', read, @@ -108,7 +108,7 @@ describe('bundleOpenApiSpecification', () => { read.mockResolvedValue(list); - const result = await bundleOpenApiSpecification( + const result = await bundleFileWithRefs( spec, 'https://github.com/owner/repo/blob/main/catalog-info.yaml', read, @@ -117,4 +117,64 @@ describe('bundleOpenApiSpecification', () => { expect(result).toEqual(expectedResult.trimStart()); }); + it('should return the bundled asyncapi specification', async () => { + const spec = ` + asyncapi: 2.5.0 + info: + version: 1.0.0 + title: Sample API + description: A sample API to illustrate OpenAPI concepts + channels: + my-topic: + subscribe: + message: + schemaFormat: "application/schema+json;version=draft-07" + payload: + $ref : "./asyncapi.schema.json" + `; + const jsonSchema = ` + { + "type": "object", + "description": "ExampleSchema", + "properties": { + "name" : { + "type": "string" + }, + "age" : { + "type" : "integer" + } + } + } + `; + const expectedSchema = ` +asyncapi: 2.5.0 +info: + version: 1.0.0 + title: Sample API + description: A sample API to illustrate OpenAPI concepts +channels: + my-topic: + subscribe: + message: + schemaFormat: application/schema+json;version=draft-07 + payload: + type: object + description: ExampleSchema + properties: + name: + type: string + age: + type: integer +`; + read.mockResolvedValue(jsonSchema); + + const result = await bundleFileWithRefs( + spec, + 'https://github.com/owner/repo/blob/main/catalog-info.yaml', + read, + resolveUrl, + ); + + expect(result).toEqual(expectedSchema.trimStart()); + }); }); diff --git a/plugins/catalog-backend-module-openapi/src/lib/bundle.ts b/plugins/catalog-backend-module-openapi/src/lib/bundle.ts index 8dd880c234..64c772b91e 100644 --- a/plugins/catalog-backend-module-openapi/src/lib/bundle.ts +++ b/plugins/catalog-backend-module-openapi/src/lib/bundle.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import SwaggerParser from '@apidevtools/swagger-parser'; +import $RefParser from '@apidevtools/json-schema-ref-parser'; import { parse, stringify } from 'yaml'; import * as path from 'path'; @@ -30,13 +30,13 @@ export type BundlerRead = (url: string) => Promise; export type BundlerResolveUrl = (url: string, base: string) => string; -export async function bundleOpenApiSpecification( - specification: string, +export async function bundleFileWithRefs( + fileWithRefs: string, baseUrl: string, read: BundlerRead, resolveUrl: BundlerResolveUrl, ): Promise { - const fileUrlReaderResolver: SwaggerParser.ResolverOptions = { + const fileUrlReaderResolver: $RefParser.ResolverOptions = { canRead: file => { const protocol = getProtocol(file.url); return protocol === undefined || protocol === 'file'; @@ -47,7 +47,7 @@ export async function bundleOpenApiSpecification( return await read(url); }, }; - const httpUrlReaderResolver: SwaggerParser.ResolverOptions = { + const httpUrlReaderResolver: $RefParser.ResolverOptions = { canRead: ref => { const protocol = getProtocol(ref.url); return protocol === 'http' || protocol === 'https'; @@ -58,13 +58,13 @@ export async function bundleOpenApiSpecification( }, }; - const options: SwaggerParser.Options = { + const options: $RefParser.Options = { resolve: { file: fileUrlReaderResolver, http: httpUrlReaderResolver, }, }; - const specObject = parse(specification); - const bundledSpec = await SwaggerParser.bundle(specObject, options); - return stringify(bundledSpec); + const fileObject = parse(fileWithRefs); + const bundledObject = await $RefParser.bundle(fileObject, options); + return stringify(bundledObject); } diff --git a/plugins/catalog-backend-module-openapi/src/openApiPlaceholderResolver.test.ts b/plugins/catalog-backend-module-openapi/src/refPlaceholderResolver.test.ts similarity index 70% rename from plugins/catalog-backend-module-openapi/src/openApiPlaceholderResolver.test.ts rename to plugins/catalog-backend-module-openapi/src/refPlaceholderResolver.test.ts index f58a818ba5..9ecf0a2995 100644 --- a/plugins/catalog-backend-module-openapi/src/openApiPlaceholderResolver.test.ts +++ b/plugins/catalog-backend-module-openapi/src/refPlaceholderResolver.test.ts @@ -14,16 +14,16 @@ * limitations under the License. */ import { PlaceholderResolverParams } from '@backstage/plugin-catalog-backend'; -import { openApiPlaceholderResolver } from './openApiPlaceholderResolver'; -import { bundleOpenApiSpecification } from './lib'; +import { refPlaceholderResolver } from './refPlaceholderResolver'; +import { bundleFileWithRefs } from './lib'; jest.mock('./lib', () => ({ - bundleOpenApiSpecification: jest.fn(), + bundleFileWithRefs: jest.fn(), })); -const bundledSpecification = ''; +const bundled = ''; -describe('openApiPlaceholderResolver', () => { +describe('refPlaceholderResolver', () => { const mockResolveUrl = jest.fn(); mockResolveUrl.mockReturnValue('mockUrl'); @@ -40,7 +40,7 @@ describe('openApiPlaceholderResolver', () => { }; beforeEach(() => { - (bundleOpenApiSpecification as any).mockResolvedValue(bundledSpecification); + (bundleFileWithRefs as any).mockResolvedValue(bundled); }); afterEach(() => { @@ -48,16 +48,16 @@ describe('openApiPlaceholderResolver', () => { }); it('should throw error if unable to bundle the OpenAPI specification', async () => { - (bundleOpenApiSpecification as any).mockRejectedValue(new Error('TEST')); + (bundleFileWithRefs as any).mockRejectedValue(new Error('TEST')); - await expect(openApiPlaceholderResolver(params)).rejects.toThrow( + await expect(refPlaceholderResolver(params)).rejects.toThrow( 'Placeholder $openapi unable to bundle OpenAPI specification', ); }); it('should bundle the OpenAPI specification', async () => { - const result = await openApiPlaceholderResolver(params); + const result = await refPlaceholderResolver(params); - expect(result).toEqual(bundledSpecification); + expect(result).toEqual(bundled); }); }); diff --git a/plugins/catalog-backend-module-openapi/src/openApiPlaceholderResolver.ts b/plugins/catalog-backend-module-openapi/src/refPlaceholderResolver.ts similarity index 94% rename from plugins/catalog-backend-module-openapi/src/openApiPlaceholderResolver.ts rename to plugins/catalog-backend-module-openapi/src/refPlaceholderResolver.ts index 96fadb3cbc..39c2e639ab 100644 --- a/plugins/catalog-backend-module-openapi/src/openApiPlaceholderResolver.ts +++ b/plugins/catalog-backend-module-openapi/src/refPlaceholderResolver.ts @@ -16,10 +16,10 @@ import { PlaceholderResolverParams } from '@backstage/plugin-catalog-backend'; import { JsonValue } from '@backstage/types'; import { processingResult } from '@backstage/plugin-catalog-node'; -import { bundleOpenApiSpecification } from './lib'; +import { bundleFileWithRefs } from './lib'; /** @public */ -export async function openApiPlaceholderResolver( +export async function refPlaceholderResolver( params: PlaceholderResolverParams, ): Promise { const { content, url } = await readTextLocation(params); @@ -27,7 +27,7 @@ export async function openApiPlaceholderResolver( params.emit(processingResult.refresh(`url:${url}`)); try { - return await bundleOpenApiSpecification( + return await bundleFileWithRefs( content, url, params.read, From 5b6ae89870d93743ecad090b66fc8718fc14fd71 Mon Sep 17 00:00:00 2001 From: Thorsten Hake Date: Fri, 11 Nov 2022 09:36:48 +0100 Subject: [PATCH 05/83] updated api-report.md Signed-off-by: Thorsten Hake --- plugins/catalog-backend-module-openapi/api-report.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/plugins/catalog-backend-module-openapi/api-report.md b/plugins/catalog-backend-module-openapi/api-report.md index d3a40067c5..9dbc899dde 100644 --- a/plugins/catalog-backend-module-openapi/api-report.md +++ b/plugins/catalog-backend-module-openapi/api-report.md @@ -13,10 +13,8 @@ import { PlaceholderResolverParams } from '@backstage/plugin-catalog-backend'; import { ScmIntegrations } from '@backstage/integration'; import { UrlReader } from '@backstage/backend-common'; -// @public (undocumented) -export function openApiPlaceholderResolver( - params: PlaceholderResolverParams, -): Promise; +// @public @deprecated (undocumented) +export const openApiPlaceholderResolver: typeof refPlaceholderResolver; // @public @deprecated (undocumented) export class OpenApiRefProcessor implements CatalogProcessor { @@ -39,5 +37,10 @@ export class OpenApiRefProcessor implements CatalogProcessor { preProcessEntity(entity: Entity, location: LocationSpec): Promise; } +// @public (undocumented) +export function refPlaceholderResolver( + params: PlaceholderResolverParams, +): Promise; + // (No @packageDocumentation comment for this package) ``` From 7da041daa7373bdfa6e41dbd9e95f355f945385c Mon Sep 17 00:00:00 2001 From: Thorsten Hake Date: Mon, 14 Nov 2022 18:49:51 +0100 Subject: [PATCH 06/83] Update plugins/catalog-backend-module-openapi/README.md Co-authored-by: Johan Haals Signed-off-by: Thorsten Hake --- plugins/catalog-backend-module-openapi/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/catalog-backend-module-openapi/README.md b/plugins/catalog-backend-module-openapi/README.md index 68e9c90e05..44e0307ac7 100644 --- a/plugins/catalog-backend-module-openapi/README.md +++ b/plugins/catalog-backend-module-openapi/README.md @@ -1,6 +1,6 @@ # Catalog Backend Module to resolve $refs in yaml documents -This is an extension module to the plugin-catalog-backend plugin, providing an extensions to resolve $refs in yamls documents. +This is an extension module to the Catalog backend, providing extensions to resolve $refs in yaml documents. With this you can split your yaml documents into multiple files and reference them. They will be bundled, using an UrlReader, during processing and stored as a single specification. From 376551522566d3c114c8df7c8ed5d6226029d731 Mon Sep 17 00:00:00 2001 From: Thorsten Hake Date: Wed, 16 Nov 2022 06:27:00 +0100 Subject: [PATCH 07/83] updated yarn.lock Signed-off-by: Thorsten Hake --- yarn.lock | 49 +++---------------------------------------------- 1 file changed, 3 insertions(+), 46 deletions(-) diff --git a/yarn.lock b/yarn.lock index b19521eb82..396a6a6e51 100644 --- a/yarn.lock +++ b/yarn.lock @@ -21,7 +21,7 @@ __metadata: languageName: node linkType: hard -"@apidevtools/json-schema-ref-parser@npm:9.0.6, @apidevtools/json-schema-ref-parser@npm:^9.0.6": +"@apidevtools/json-schema-ref-parser@npm:^9.0.6": version: 9.0.6 resolution: "@apidevtools/json-schema-ref-parser@npm:9.0.6" dependencies: @@ -32,37 +32,6 @@ __metadata: languageName: node linkType: hard -"@apidevtools/openapi-schemas@npm:^2.1.0": - version: 2.1.0 - resolution: "@apidevtools/openapi-schemas@npm:2.1.0" - checksum: 4a8f64935b9049ef21e41fa4b188f39f6bc3f5291cebd451701db1115451ccb246a739e46cc5ce9ecdec781671431db40db7851acdac84a990a45756e0f32de3 - languageName: node - linkType: hard - -"@apidevtools/swagger-methods@npm:^3.0.2": - version: 3.0.2 - resolution: "@apidevtools/swagger-methods@npm:3.0.2" - checksum: d06b1ac5c1956613c4c6be695612ef860cd4e962b93a509ca551735a328a856cae1e33399cac1dcbf8333ba22b231746f3586074769ef0e172cf549ec9e7eaae - languageName: node - linkType: hard - -"@apidevtools/swagger-parser@npm:^10.1.0": - version: 10.1.0 - resolution: "@apidevtools/swagger-parser@npm:10.1.0" - dependencies: - "@apidevtools/json-schema-ref-parser": 9.0.6 - "@apidevtools/openapi-schemas": ^2.1.0 - "@apidevtools/swagger-methods": ^3.0.2 - "@jsdevtools/ono": ^7.1.3 - ajv: ^8.6.3 - ajv-draft-04: ^1.0.0 - call-me-maybe: ^1.0.1 - peerDependencies: - openapi-types: ">=7" - checksum: c7c923755bd025ee2cae97e1cfd525538523ba74c341a0ac814c023ffe5e63fc2d997539a8ccf9a0fcec41a2d6337d40cc5735acb991ddcbb415853a241908d1 - languageName: node - linkType: hard - "@apollo/explorer@npm:^1.1.1": version: 1.2.0 resolution: "@apollo/explorer@npm:1.2.0" @@ -4478,7 +4447,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-backend-module-openapi@workspace:plugins/catalog-backend-module-openapi" dependencies: - "@apidevtools/swagger-parser": ^10.1.0 + "@apidevtools/json-schema-ref-parser": ^9.0.6 "@backstage/backend-common": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/catalog-model": "workspace:^" @@ -14990,18 +14959,6 @@ __metadata: languageName: node linkType: hard -"ajv-draft-04@npm:^1.0.0": - version: 1.0.0 - resolution: "ajv-draft-04@npm:1.0.0" - peerDependencies: - ajv: ^8.5.0 - peerDependenciesMeta: - ajv: - optional: true - checksum: 3f11fa0e7f7359bef6608657f02ab78e9cc62b1fb7bdd860db0d00351b3863a1189c1a23b72466d2d82726cab4eb20725c76f5e7c134a89865e2bfd0e6828137 - languageName: node - linkType: hard - "ajv-formats@npm:^2.1.1": version: 2.1.1 resolution: "ajv-formats@npm:2.1.1" @@ -15048,7 +15005,7 @@ __metadata: languageName: node linkType: hard -"ajv@npm:^8.0.0, ajv@npm:^8.10.0, ajv@npm:^8.11.0, ajv@npm:^8.6.3, ajv@npm:^8.8.0": +"ajv@npm:^8.0.0, ajv@npm:^8.10.0, ajv@npm:^8.11.0, ajv@npm:^8.8.0": version: 8.11.2 resolution: "ajv@npm:8.11.2" dependencies: From a5ecdb99f036e1a24e6565f4db23f5190cf9b119 Mon Sep 17 00:00:00 2001 From: bnechyporenko Date: Wed, 16 Nov 2022 10:57:36 +0100 Subject: [PATCH 08/83] Making a possibility to hide a trending line in a cost insights plugin Signed-off-by: bnechyporenko --- .changeset/yellow-forks-knock.md | 5 ++++ plugins/cost-insights/api-report.md | 2 +- .../CostOverviewCard/CostOverviewChart.tsx | 25 +++++++++------- plugins/cost-insights/src/options.ts | 29 +++++++++++++++++++ plugins/cost-insights/src/plugin.ts | 12 ++++++++ 5 files changed, 62 insertions(+), 11 deletions(-) create mode 100644 .changeset/yellow-forks-knock.md create mode 100644 plugins/cost-insights/src/options.ts diff --git a/.changeset/yellow-forks-knock.md b/.changeset/yellow-forks-knock.md new file mode 100644 index 0000000000..98c4b5b675 --- /dev/null +++ b/.changeset/yellow-forks-knock.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-cost-insights': patch +--- + +Making a possibility to hide a trending line in a cost insights plugin diff --git a/plugins/cost-insights/api-report.md b/plugins/cost-insights/api-report.md index dd4e404450..27f7c94f21 100644 --- a/plugins/cost-insights/api-report.md +++ b/plugins/cost-insights/api-report.md @@ -316,7 +316,7 @@ const costInsightsPlugin: BackstagePlugin< unlabeledDataflowAlerts: RouteRef; }, {}, - {} + CostInsightsInputPluginOptions >; export { costInsightsPlugin }; export { costInsightsPlugin as plugin }; diff --git a/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewChart.tsx b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewChart.tsx index 1c58bf58e6..687f9bdd39 100644 --- a/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewChart.tsx +++ b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewChart.tsx @@ -48,7 +48,8 @@ import { useCostOverviewStyles as useStyles } from '../../utils/styles'; import { groupByDate, toDataMax, trendFrom } from '../../utils/charts'; import { aggregationSort } from '../../utils/sort'; import { CostOverviewLegend } from './CostOverviewLegend'; -import { TooltipRenderer } from '../../types/Tooltip'; +import { TooltipRenderer } from '../../types'; +import { useCostInsightsOptions } from '../../options'; type CostOverviewChartProps = { metric: Maybe; @@ -132,6 +133,8 @@ export const CostOverviewChart = ({ ); }; + const { showTrendLine } = useCostInsightsOptions(); + return ( - + {showTrendLine && ( + + )} {metric && ( + usePluginOptions(); diff --git a/plugins/cost-insights/src/plugin.ts b/plugins/cost-insights/src/plugin.ts index 04d58d1877..1d776660ce 100644 --- a/plugins/cost-insights/src/plugin.ts +++ b/plugins/cost-insights/src/plugin.ts @@ -19,6 +19,10 @@ import { createRouteRef, createRoutableExtension, } from '@backstage/core-plugin-api'; +import { + CostInsightsInputPluginOptions, + CostInsightsPluginOptions, +} from './options'; export const rootRouteRef = createRouteRef({ id: 'cost-insights', @@ -41,6 +45,14 @@ export const costInsightsPlugin = createPlugin({ growthAlerts: projectGrowthAlertRef, unlabeledDataflowAlerts: unlabeledDataflowAlertRef, }, + __experimentalConfigure( + options?: CostInsightsInputPluginOptions, + ): CostInsightsPluginOptions { + const defaultOptions = { + showTrendLine: true, + }; + return { ...defaultOptions, ...options }; + }, }); /** @public */ From c860237e31e64a5331404264ade182f79a2bf8d0 Mon Sep 17 00:00:00 2001 From: bnechyporenko Date: Wed, 16 Nov 2022 12:39:56 +0100 Subject: [PATCH 09/83] Test fixes Signed-off-by: bnechyporenko --- .../CostOverviewCard.test.tsx | 20 ++++++++++++++++++- .../EntityCosts/EntityCost.test.tsx | 20 ++++++++++++++++++- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewCard.test.tsx b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewCard.test.tsx index e3de9593d9..ca438b75ac 100644 --- a/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewCard.test.tsx +++ b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewCard.test.tsx @@ -30,6 +30,7 @@ import { MockScrollProvider, } from '../../testUtils'; import { CostInsightsThemeProvider } from '../CostInsightsPage/CostInsightsThemeProvider'; +import { createPlugin, PluginProvider } from '@backstage/core-plugin-api'; const mockGroupDailyCost: Cost = { id: 'test-group', @@ -38,13 +39,30 @@ const mockGroupDailyCost: Cost = { trendline: trendlineOf(MockAggregatedDailyCosts), }; +type TestInputPluginOptions = { + showTrendLine: boolean; +}; + +type TestPluginOptions = { + showTrendLine: boolean; +}; + +const plugin = createPlugin({ + id: 'my-plugin', + __experimentalConfigure(_: TestInputPluginOptions): TestPluginOptions { + return { showTrendLine: false }; + }, +}); + function renderInContext(children: JSX.Element) { return renderInTestApp( - {children} + + {children} + diff --git a/plugins/cost-insights/src/components/EntityCosts/EntityCost.test.tsx b/plugins/cost-insights/src/components/EntityCosts/EntityCost.test.tsx index 53e1a13ebf..e2b6a28247 100644 --- a/plugins/cost-insights/src/components/EntityCosts/EntityCost.test.tsx +++ b/plugins/cost-insights/src/components/EntityCosts/EntityCost.test.tsx @@ -32,6 +32,7 @@ import { EntityProvider } from '@backstage/plugin-catalog-react'; import { Entity } from '@backstage/catalog-model'; import { LoadingProvider } from '../../hooks'; import { Cost } from '@backstage/plugin-cost-insights-common'; +import { createPlugin, PluginProvider } from '@backstage/core-plugin-api'; function renderInContext(children: JSX.Element) { const mockEntity = { @@ -56,6 +57,21 @@ function renderInContext(children: JSX.Element) { getAlerts: jest.fn().mockResolvedValue({}), }; + type TestInputPluginOptions = { + showTrendLine: boolean; + }; + + type TestPluginOptions = { + showTrendLine: boolean; + }; + + const plugin = createPlugin({ + id: 'my-plugin', + __experimentalConfigure(_: TestInputPluginOptions): TestPluginOptions { + return { showTrendLine: false }; + }, + }); + return renderInTestApp( @@ -64,7 +80,9 @@ function renderInContext(children: JSX.Element) { - {children} + + {children} + From 8536e7c281e74b7df5ecc413f31c795e9983cebe Mon Sep 17 00:00:00 2001 From: skgandikota Date: Wed, 16 Nov 2022 20:26:04 +0530 Subject: [PATCH 10/83] Refactored Report issue template in techdoc addons. Co-authored-by: kcheriyath Co-authored-by: aswathysen Co-authored-by: skgandikota Signed-off-by: skgandikota --- .changeset/tender-parrots-cover.md | 5 +++++ .../src/ReportIssue/hooks.ts | 15 ++++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) create mode 100644 .changeset/tender-parrots-cover.md diff --git a/.changeset/tender-parrots-cover.md b/.changeset/tender-parrots-cover.md new file mode 100644 index 0000000000..433d030628 --- /dev/null +++ b/.changeset/tender-parrots-cover.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs-module-addons-contrib': patch +--- + +Refactored Report issue body in the tech-doc addons by getting the app title from `appconfig.yml` using `configApiRef`, In case `appTitle` not mentioned app Tile `new const` will default to `Backstage` diff --git a/plugins/techdocs-module-addons-contrib/src/ReportIssue/hooks.ts b/plugins/techdocs-module-addons-contrib/src/ReportIssue/hooks.ts index 22dc359942..302568ce9c 100644 --- a/plugins/techdocs-module-addons-contrib/src/ReportIssue/hooks.ts +++ b/plugins/techdocs-module-addons-contrib/src/ReportIssue/hooks.ts @@ -16,7 +16,7 @@ import parseGitUrl from 'git-url-parse'; -import { useApi } from '@backstage/core-plugin-api'; +import { configApiRef, useApi } from '@backstage/core-plugin-api'; import { replaceGithubUrlType, replaceGitLabUrlType, @@ -48,7 +48,11 @@ export const getTitle = (selection: Selection) => { return `Documentation feedback: ${text}${ellipsis}`; }; -export const getBody = (selection: Selection, markdownUrl: string) => { +export const getBody = ( + selection: Selection, + markdownUrl: string, + appTitle: string, +) => { const title = '## Documentation Feedback 📝'; const subheading = '#### The highlighted text:'; const commentHeading = '#### The comment on the text:'; @@ -61,7 +65,7 @@ export const getBody = (selection: Selection, markdownUrl: string) => { .join('\n'); const facts = [ - `Backstage URL: <${window.location.href}> \nMarkdown URL: <${markdownUrl}>`, + `${appTitle} URL: <${window.location.href}> \nMarkdown URL: <${markdownUrl}>`, ]; return `${title}\n\n ${subheading} \n\n ${highlightedTextAsQuote}\n\n ${commentHeading} \n ${commentPlaceholder}\n\n ___\n${facts}`; @@ -73,7 +77,8 @@ export const useGitTemplate = (debounceTime?: number) => { const [editLink] = useShadowRootElements([PAGE_EDIT_LINK_SELECTOR]); const url = (editLink as HTMLAnchorElement)?.href ?? ''; const scmIntegrationsApi = useApi(scmIntegrationsApiRef); - + const configApi = useApi(configApiRef); + const appTitle = configApi.getOptional('app.title') || 'Backstage'; if (!selection || !url) return initialTemplate; const type = scmIntegrationsApi.byUrl(url)?.type; @@ -82,7 +87,7 @@ export const useGitTemplate = (debounceTime?: number) => { return { title: getTitle(selection), - body: getBody(selection, resolveBlobUrl(url, type)), + body: getBody(selection, resolveBlobUrl(url, type), appTitle), }; }; From c03fc0509f5f921ed2e40684c1c6a06bfb86f2e2 Mon Sep 17 00:00:00 2001 From: skgandikota Date: Wed, 16 Nov 2022 20:40:56 +0530 Subject: [PATCH 11/83] Refactored Report issue template in techdoc addons. Co-authored-by: kcheriyath Co-authored-by: aswathysen Signed-off-by: skgandikota --- plugins/techdocs-module-addons-contrib/src/ReportIssue/hooks.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/techdocs-module-addons-contrib/src/ReportIssue/hooks.ts b/plugins/techdocs-module-addons-contrib/src/ReportIssue/hooks.ts index 302568ce9c..bfe7331827 100644 --- a/plugins/techdocs-module-addons-contrib/src/ReportIssue/hooks.ts +++ b/plugins/techdocs-module-addons-contrib/src/ReportIssue/hooks.ts @@ -78,7 +78,7 @@ export const useGitTemplate = (debounceTime?: number) => { const url = (editLink as HTMLAnchorElement)?.href ?? ''; const scmIntegrationsApi = useApi(scmIntegrationsApiRef); const configApi = useApi(configApiRef); - const appTitle = configApi.getOptional('app.title') || 'Backstage'; + let appTitle: string = configApi.getOptional('app.title') || 'Backstage'; if (!selection || !url) return initialTemplate; const type = scmIntegrationsApi.byUrl(url)?.type; From 27ee635e4d4123a5ab82d73ad9aa47779b4b2c2f Mon Sep 17 00:00:00 2001 From: skgandikota Date: Wed, 16 Nov 2022 20:49:37 +0530 Subject: [PATCH 12/83] fix: lint fix 'appTitle' is never reassigned. Use 'const' instead Co-authored-by: kcheriyath Co-authored-by: aswathysen Signed-off-by: skgandikota --- plugins/techdocs-module-addons-contrib/src/ReportIssue/hooks.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/techdocs-module-addons-contrib/src/ReportIssue/hooks.ts b/plugins/techdocs-module-addons-contrib/src/ReportIssue/hooks.ts index bfe7331827..800a422066 100644 --- a/plugins/techdocs-module-addons-contrib/src/ReportIssue/hooks.ts +++ b/plugins/techdocs-module-addons-contrib/src/ReportIssue/hooks.ts @@ -78,7 +78,7 @@ export const useGitTemplate = (debounceTime?: number) => { const url = (editLink as HTMLAnchorElement)?.href ?? ''; const scmIntegrationsApi = useApi(scmIntegrationsApiRef); const configApi = useApi(configApiRef); - let appTitle: string = configApi.getOptional('app.title') || 'Backstage'; + const appTitle = configApi.getOptionalString('app.title') || 'Backstage'; if (!selection || !url) return initialTemplate; const type = scmIntegrationsApi.byUrl(url)?.type; From 9e824cfd4a530843ab554e1cadc0799ff48bac32 Mon Sep 17 00:00:00 2001 From: bogdannechyporenko Date: Wed, 16 Nov 2022 21:17:12 +0100 Subject: [PATCH 13/83] Incorporated the feedback Signed-off-by: bogdannechyporenko --- .../CostOverviewCard.test.tsx | 19 ++--------------- .../CostOverviewCard/CostOverviewChart.tsx | 4 ++-- .../EntityCosts/EntityCost.test.tsx | 21 ++++--------------- plugins/cost-insights/src/options.ts | 4 ++-- plugins/cost-insights/src/plugin.ts | 2 +- .../cost-insights/src/testUtils/providers.tsx | 14 +++++++++++++ 6 files changed, 25 insertions(+), 39 deletions(-) diff --git a/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewCard.test.tsx b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewCard.test.tsx index ca438b75ac..074c3a64bd 100644 --- a/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewCard.test.tsx +++ b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewCard.test.tsx @@ -28,9 +28,9 @@ import { MockConfigProvider, MockFilterProvider, MockScrollProvider, + MockPluginProvider, } from '../../testUtils'; import { CostInsightsThemeProvider } from '../CostInsightsPage/CostInsightsThemeProvider'; -import { createPlugin, PluginProvider } from '@backstage/core-plugin-api'; const mockGroupDailyCost: Cost = { id: 'test-group', @@ -39,21 +39,6 @@ const mockGroupDailyCost: Cost = { trendline: trendlineOf(MockAggregatedDailyCosts), }; -type TestInputPluginOptions = { - showTrendLine: boolean; -}; - -type TestPluginOptions = { - showTrendLine: boolean; -}; - -const plugin = createPlugin({ - id: 'my-plugin', - __experimentalConfigure(_: TestInputPluginOptions): TestPluginOptions { - return { showTrendLine: false }; - }, -}); - function renderInContext(children: JSX.Element) { return renderInTestApp( @@ -61,7 +46,7 @@ function renderInContext(children: JSX.Element) { - {children} + {children} diff --git a/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewChart.tsx b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewChart.tsx index 687f9bdd39..f91fe472c6 100644 --- a/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewChart.tsx +++ b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewChart.tsx @@ -133,7 +133,7 @@ export const CostOverviewChart = ({ ); }; - const { showTrendLine } = useCostInsightsOptions(); + const { hideTrendLine } = useCostInsightsOptions(); return ( @@ -180,7 +180,7 @@ export const CostOverviewChart = ({ stroke="none" yAxisId={data.dailyCost.dataKey} /> - {showTrendLine && ( + {!hideTrendLine && ( @@ -81,7 +66,9 @@ function renderInContext(children: JSX.Element) { - {children} + + {children} + diff --git a/plugins/cost-insights/src/options.ts b/plugins/cost-insights/src/options.ts index 820bea7654..287935d703 100644 --- a/plugins/cost-insights/src/options.ts +++ b/plugins/cost-insights/src/options.ts @@ -17,12 +17,12 @@ import { usePluginOptions } from '@backstage/core-plugin-api'; export type CostInsightsPluginOptions = { - showTrendLine: boolean; + hideTrendLine?: boolean; }; /** @ignore */ export type CostInsightsInputPluginOptions = { - showTrendLine: boolean; + hideTrendLine?: boolean; }; export const useCostInsightsOptions = () => diff --git a/plugins/cost-insights/src/plugin.ts b/plugins/cost-insights/src/plugin.ts index 1d776660ce..c863c9e03a 100644 --- a/plugins/cost-insights/src/plugin.ts +++ b/plugins/cost-insights/src/plugin.ts @@ -49,7 +49,7 @@ export const costInsightsPlugin = createPlugin({ options?: CostInsightsInputPluginOptions, ): CostInsightsPluginOptions { const defaultOptions = { - showTrendLine: true, + hideTrendLine: false, }; return { ...defaultOptions, ...options }; }, diff --git a/plugins/cost-insights/src/testUtils/providers.tsx b/plugins/cost-insights/src/testUtils/providers.tsx index 8088fca3c6..f8d23dda3c 100644 --- a/plugins/cost-insights/src/testUtils/providers.tsx +++ b/plugins/cost-insights/src/testUtils/providers.tsx @@ -26,6 +26,7 @@ import { } from '../hooks/useLastCompleteBillingDate'; import { ScrollContext, ScrollContextProps } from '../hooks/useScroll'; import { Group, Duration } from '../types'; +import { createPlugin, PluginProvider } from '@backstage/core-plugin-api'; export const MockGroups: Group[] = [{ id: 'tech' }, { id: 'mock-group' }]; @@ -144,6 +145,19 @@ export const MockBillingDateProvider = ({ export type MockScrollProviderProps = PropsWithChildren<{}>; +export const MockPluginProvider = ({ children }: PropsWithChildren<{}>) => { + type TestInputPluginOptions = {}; + type TestPluginOptions = {}; + const plugin = createPlugin({ + id: 'my-plugin', + __experimentalConfigure(_: TestInputPluginOptions): TestPluginOptions { + return {}; + }, + }); + + return {children}; +}; + export const MockScrollProvider = ({ children }: MockScrollProviderProps) => { const defaultContext: ScrollContextProps = { scroll: null, From 03360e1d40c86be3a0e6c1e7afbb530ed85136d6 Mon Sep 17 00:00:00 2001 From: bogdannechyporenko Date: Thu, 17 Nov 2022 16:58:58 +0100 Subject: [PATCH 14/83] Incorporated the feedback Signed-off-by: bogdannechyporenko --- packages/test-utils/src/testUtils/index.tsx | 1 + .../test-utils/src/testUtils/providers.tsx | 31 +++++++++++++++++ .../CatalogPage/DefaultCatalogPage.test.tsx | 23 ++----------- plugins/cost-insights/package.json | 1 + .../CostOverviewCard.test.tsx | 5 ++- .../EntityCosts/EntityCost.test.tsx | 8 +++-- .../cost-insights/src/testUtils/providers.tsx | 34 +++++++------------ 7 files changed, 56 insertions(+), 47 deletions(-) create mode 100644 packages/test-utils/src/testUtils/providers.tsx diff --git a/packages/test-utils/src/testUtils/index.tsx b/packages/test-utils/src/testUtils/index.tsx index bfd870e2ad..1df236d92c 100644 --- a/packages/test-utils/src/testUtils/index.tsx +++ b/packages/test-utils/src/testUtils/index.tsx @@ -24,6 +24,7 @@ export { export type { TestAppOptions } from './appWrappers'; export * from './msw'; export * from './logCollector'; +export * from './providers'; export * from './testingLibrary'; export { TestApiProvider, TestApiRegistry } from './TestApiProvider'; export type { TestApiProviderProps } from './TestApiProvider'; diff --git a/packages/test-utils/src/testUtils/providers.tsx b/packages/test-utils/src/testUtils/providers.tsx new file mode 100644 index 0000000000..cf4787099b --- /dev/null +++ b/packages/test-utils/src/testUtils/providers.tsx @@ -0,0 +1,31 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React, { PropsWithChildren } from 'react'; +import { createPlugin, PluginProvider } from '@backstage/core-plugin-api'; + +export const MockPluginProvider = ({ children }: PropsWithChildren<{}>) => { + type TestInputPluginOptions = {}; + type TestPluginOptions = {}; + const plugin = createPlugin({ + id: 'my-plugin', + __experimentalConfigure(_: TestInputPluginOptions): TestPluginOptions { + return {}; + }, + }); + + return {children}; +}; diff --git a/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.test.tsx b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.test.tsx index cc00a57314..4636db5576 100644 --- a/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.test.tsx +++ b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.test.tsx @@ -23,21 +23,20 @@ import { } from '@backstage/catalog-model'; import { TableColumn, TableProps } from '@backstage/core-components'; import { - createPlugin, IdentityApi, identityApiRef, - PluginProvider, ProfileInfo, storageApiRef, } from '@backstage/core-plugin-api'; import { catalogApiRef, entityRouteRef, - starredEntitiesApiRef, MockStarredEntitiesApi, + starredEntitiesApiRef, } from '@backstage/plugin-catalog-react'; import { mockBreakpoint, + MockPluginProvider, MockStorageApi, renderWithEffects, TestApiProvider, @@ -135,22 +134,6 @@ describe('DefaultCatalogPage', () => { }; const storageApi = MockStorageApi.create(); - type TestInputPluginOptions = { - 'key-1': string; - }; - - type TestPluginOptions = { - 'key-1': string; - 'key-2': string; - }; - - const plugin = createPlugin({ - id: 'my-plugin', - __experimentalConfigure(_: TestInputPluginOptions): TestPluginOptions { - return { 'key-1': 'value-1', 'key-2': 'value-2' }; - }, - }); - const renderWrapped = (children: React.ReactNode) => renderWithEffects( wrapInTestApp( @@ -162,7 +145,7 @@ describe('DefaultCatalogPage', () => { [starredEntitiesApiRef, new MockStarredEntitiesApi()], ]} > - {children} + {children} , { mountedRoutes: { diff --git a/plugins/cost-insights/package.json b/plugins/cost-insights/package.json index 3ef57bf70b..8f383b5d47 100644 --- a/plugins/cost-insights/package.json +++ b/plugins/cost-insights/package.json @@ -38,6 +38,7 @@ "@backstage/core-plugin-api": "workspace:^", "@backstage/plugin-catalog-react": "workspace:^", "@backstage/plugin-cost-insights-common": "workspace:^", + "@backstage/test-utils": "workspace:^", "@backstage/theme": "workspace:^", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", diff --git a/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewCard.test.tsx b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewCard.test.tsx index 074c3a64bd..e8fbb7abcb 100644 --- a/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewCard.test.tsx +++ b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewCard.test.tsx @@ -15,7 +15,7 @@ */ import React from 'react'; import { fireEvent } from '@testing-library/react'; -import { renderInTestApp } from '@backstage/test-utils'; +import { MockPluginProvider, renderInTestApp } from '@backstage/test-utils'; import { CostOverviewCard } from './CostOverviewCard'; import { Cost } from '../../types'; import { @@ -23,12 +23,11 @@ import { getGroupedProducts, getGroupedProjects, MockAggregatedDailyCosts, - trendlineOf, MockBillingDateProvider, MockConfigProvider, MockFilterProvider, MockScrollProvider, - MockPluginProvider, + trendlineOf, } from '../../testUtils'; import { CostInsightsThemeProvider } from '../CostInsightsPage/CostInsightsThemeProvider'; diff --git a/plugins/cost-insights/src/components/EntityCosts/EntityCost.test.tsx b/plugins/cost-insights/src/components/EntityCosts/EntityCost.test.tsx index da3f4300bb..f288f54e9b 100644 --- a/plugins/cost-insights/src/components/EntityCosts/EntityCost.test.tsx +++ b/plugins/cost-insights/src/components/EntityCosts/EntityCost.test.tsx @@ -14,20 +14,22 @@ * limitations under the License. */ import React from 'react'; -import { renderInTestApp } from '@backstage/test-utils'; +import { + MockPluginProvider, + renderInTestApp, + TestApiProvider, +} from '@backstage/test-utils'; import { changeOf, MockAggregatedDailyCosts, MockBillingDateProvider, MockConfigProvider, MockFilterProvider, - MockPluginProvider, MockScrollProvider, trendlineOf, } from '../../testUtils'; import { CostInsightsThemeProvider } from '../CostInsightsPage/CostInsightsThemeProvider'; import { EntityCostsCard } from './EntityCosts'; -import { TestApiProvider } from '@backstage/test-utils'; import { CostInsightsApi, costInsightsApiRef } from '../../api'; import { EntityProvider } from '@backstage/plugin-catalog-react'; import { Entity } from '@backstage/catalog-model'; diff --git a/plugins/cost-insights/src/testUtils/providers.tsx b/plugins/cost-insights/src/testUtils/providers.tsx index f8d23dda3c..a8610c44ba 100644 --- a/plugins/cost-insights/src/testUtils/providers.tsx +++ b/plugins/cost-insights/src/testUtils/providers.tsx @@ -15,18 +15,23 @@ */ import React, { PropsWithChildren } from 'react'; -import { LoadingContext, LoadingContextProps } from '../hooks/useLoading'; -import { GroupsContext, GroupsContextProps } from '../hooks/useGroups'; -import { FilterContext, FilterContextProps } from '../hooks/useFilters'; -import { ConfigContext, ConfigContextProps } from '../hooks/useConfig'; -import { CurrencyContext, CurrencyContextProps } from '../hooks/useCurrency'; import { + LoadingContext, + LoadingContextProps, + GroupsContext, + GroupsContextProps, + FilterContext, + FilterContextProps, + ConfigContext, + ConfigContextProps, + CurrencyContext, + CurrencyContextProps, BillingDateContext, BillingDateContextProps, -} from '../hooks/useLastCompleteBillingDate'; -import { ScrollContext, ScrollContextProps } from '../hooks/useScroll'; + ScrollContext, + ScrollContextProps, +} from '../hooks'; import { Group, Duration } from '../types'; -import { createPlugin, PluginProvider } from '@backstage/core-plugin-api'; export const MockGroups: Group[] = [{ id: 'tech' }, { id: 'mock-group' }]; @@ -145,19 +150,6 @@ export const MockBillingDateProvider = ({ export type MockScrollProviderProps = PropsWithChildren<{}>; -export const MockPluginProvider = ({ children }: PropsWithChildren<{}>) => { - type TestInputPluginOptions = {}; - type TestPluginOptions = {}; - const plugin = createPlugin({ - id: 'my-plugin', - __experimentalConfigure(_: TestInputPluginOptions): TestPluginOptions { - return {}; - }, - }); - - return {children}; -}; - export const MockScrollProvider = ({ children }: MockScrollProviderProps) => { const defaultContext: ScrollContextProps = { scroll: null, From 468cd24becb97e3ce79c97acb8bff350af6870a8 Mon Sep 17 00:00:00 2001 From: Max Morton Date: Thu, 17 Nov 2022 09:05:46 -0800 Subject: [PATCH 15/83] Revert "add api-report" This reverts commit b7cda00d33ef431fddc39ff75e421d4b962ff6e0. Signed-off-by: Max Morton --- packages/backend-common/api-report.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/backend-common/api-report.md b/packages/backend-common/api-report.md index 69d94053b3..e8dbd8d150 100644 --- a/packages/backend-common/api-report.md +++ b/packages/backend-common/api-report.md @@ -458,10 +458,6 @@ export class GitlabUrlReader implements UrlReader { // (undocumented) static factory: ReaderFactory; // (undocumented) - getGitlabArtifactFetchUrl(target: string): Promise; - // (undocumented) - getGitlabFetchUrl(target: string): Promise; - // (undocumented) read(url: string): Promise; // (undocumented) readTree(url: string, options?: ReadTreeOptions): Promise; From fb6b4036474c9f5073b77bb68f753d8136328217 Mon Sep 17 00:00:00 2001 From: Max Morton Date: Thu, 17 Nov 2022 09:11:59 -0800 Subject: [PATCH 16/83] Make functions private Signed-off-by: Max Morton --- .../src/reading/GitlabUrlReader.test.ts | 18 +++++++++--------- .../src/reading/GitlabUrlReader.ts | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/backend-common/src/reading/GitlabUrlReader.test.ts b/packages/backend-common/src/reading/GitlabUrlReader.test.ts index d88c6d8fb9..8bf0328432 100644 --- a/packages/backend-common/src/reading/GitlabUrlReader.test.ts +++ b/packages/backend-common/src/reading/GitlabUrlReader.test.ts @@ -585,7 +585,7 @@ describe('GitlabUrlReader', () => { }); it('should fall back to getGitLabFileFetchUrl for blob urls', async () => { await expect( - gitlabProcessor.getGitlabFetchUrl( + (gitlabProcessor as any).getGitlabFetchUrl( 'https://gitlab.com/group/subgroup/project/-/blob/branch/my/path/to/file.yaml', ), ).resolves.toEqual( @@ -594,7 +594,7 @@ describe('GitlabUrlReader', () => { }); it('should work for job artifact urls', async () => { await expect( - gitlabProcessor.getGitlabFetchUrl( + (gitlabProcessor as any).getGitlabFetchUrl( 'https://gitlab.com/group/subgroup/project/-/jobs/artifacts/branch/raw/my/path/to/file.yaml?job=myJob', ), ).resolves.toEqual( @@ -603,13 +603,13 @@ describe('GitlabUrlReader', () => { }); it('should pass API urls naively', async () => { const apiUrl = 'https://gitlab.com/api/v4/my/api/path'; - await expect(gitlabProcessor.getGitlabFetchUrl(apiUrl)).resolves.toEqual( - apiUrl, - ); + await expect( + (gitlabProcessor as any).getGitlabFetchUrl(apiUrl) + ).resolves.toEqual(apiUrl,); }); it('should fail on unfamiliar or non-Gitlab urls', async () => { await expect( - gitlabProcessor.getGitlabFetchUrl( + (gitlabProcessor as any).getGitlabFetchUrl( 'https://gitlab.com/some/random/endpoint', ), ).rejects.toThrow('Please provide full path to yaml file from GitLab'); @@ -633,14 +633,14 @@ describe('GitlabUrlReader', () => { }); it('should reject urls that are not for the job artifacts API', async () => { await expect( - gitlabProcessor.getGitlabArtifactFetchUrl( + (gitlabProcessor as any).getGitlabArtifactFetchUrl( 'https://gitlab.com/some/url', ), ).rejects.toThrow('Unable to process url as an GitLab artifact'); }); it('should work for job artifact urls', async () => { await expect( - gitlabProcessor.getGitlabFetchUrl( + (gitlabProcessor as any).getGitlabFetchUrl( 'https://gitlab.com/group/subgroup/project/-/jobs/artifacts/branch/raw/my/path/to/file.yaml?job=myJob', ), ).resolves.toEqual( @@ -649,7 +649,7 @@ describe('GitlabUrlReader', () => { }); it('errors in mapping the project ID should be captured', async () => { await expect( - gitlabProcessor.getGitlabFetchUrl( + (gitlabProcessor as any).getGitlabFetchUrl( 'https://gitlab.com/groupA/subgroup/project/-/jobs/artifacts/branch/raw/my/path/to/file.yaml?job=myJob', ), ).rejects.toThrow(/^Unable to translate GitLab artifact URL:/); diff --git a/packages/backend-common/src/reading/GitlabUrlReader.ts b/packages/backend-common/src/reading/GitlabUrlReader.ts index f704901650..3455de6f20 100644 --- a/packages/backend-common/src/reading/GitlabUrlReader.ts +++ b/packages/backend-common/src/reading/GitlabUrlReader.ts @@ -257,7 +257,7 @@ export class GitlabUrlReader implements UrlReader { return `gitlab{host=${host},authed=${Boolean(token)}}`; } - async getGitlabFetchUrl(target: string): Promise { + private async getGitlabFetchUrl(target: string): Promise { // If the target is a raw API url then trust that no parsing is needed if (target.includes('/api/v4/')) { return target; @@ -276,7 +276,7 @@ export class GitlabUrlReader implements UrlReader { // https://example.com///-/jobs/artifacts//raw/?job= // to urls of the form: // https://example.com/api/v4/projects/:id/jobs/artifacts/:ref_name/raw/*artifact_path?job= - async getGitlabArtifactFetchUrl(target: string): Promise { + private async getGitlabArtifactFetchUrl(target: string): Promise { const url = new URL(target); if (!url.pathname.includes('/-/jobs/artifacts/')) { throw new Error('Unable to process url as an GitLab artifact'); From 15841df6df40eb7bcb56f7c36f11680d3f2fe4a4 Mon Sep 17 00:00:00 2001 From: Max Morton Date: Thu, 17 Nov 2022 10:21:39 -0800 Subject: [PATCH 17/83] remove naive /api/v4 querying Signed-off-by: Max Morton --- packages/backend-common/src/reading/GitlabUrlReader.test.ts | 6 ------ packages/backend-common/src/reading/GitlabUrlReader.ts | 4 ---- 2 files changed, 10 deletions(-) diff --git a/packages/backend-common/src/reading/GitlabUrlReader.test.ts b/packages/backend-common/src/reading/GitlabUrlReader.test.ts index 8bf0328432..caf82f2f9e 100644 --- a/packages/backend-common/src/reading/GitlabUrlReader.test.ts +++ b/packages/backend-common/src/reading/GitlabUrlReader.test.ts @@ -601,12 +601,6 @@ describe('GitlabUrlReader', () => { 'https://gitlab.com/api/v4/projects/12345/jobs/artifacts/branch/raw/my/path/to/file.yaml?job=myJob', ); }); - it('should pass API urls naively', async () => { - const apiUrl = 'https://gitlab.com/api/v4/my/api/path'; - await expect( - (gitlabProcessor as any).getGitlabFetchUrl(apiUrl) - ).resolves.toEqual(apiUrl,); - }); it('should fail on unfamiliar or non-Gitlab urls', async () => { await expect( (gitlabProcessor as any).getGitlabFetchUrl( diff --git a/packages/backend-common/src/reading/GitlabUrlReader.ts b/packages/backend-common/src/reading/GitlabUrlReader.ts index 3455de6f20..f54e045857 100644 --- a/packages/backend-common/src/reading/GitlabUrlReader.ts +++ b/packages/backend-common/src/reading/GitlabUrlReader.ts @@ -258,10 +258,6 @@ export class GitlabUrlReader implements UrlReader { } private async getGitlabFetchUrl(target: string): Promise { - // If the target is a raw API url then trust that no parsing is needed - if (target.includes('/api/v4/')) { - return target; - } // If the target is for a job artifact then go down that path if (target.includes('/-/jobs/artifacts/')) { return this.getGitlabArtifactFetchUrl(target).then(value => From c0f423a54c9df5424dc0c0decb9308922c2b170b Mon Sep 17 00:00:00 2001 From: bogdannechyporenko Date: Thu, 17 Nov 2022 20:06:15 +0100 Subject: [PATCH 18/83] Fixed build issues Signed-off-by: bogdannechyporenko --- .changeset/yellow-forks-knock.md | 1 + packages/test-utils/api-report.md | 6 ++++++ packages/test-utils/src/testUtils/providers.tsx | 4 ++++ 3 files changed, 11 insertions(+) diff --git a/.changeset/yellow-forks-knock.md b/.changeset/yellow-forks-knock.md index 98c4b5b675..6c3d300026 100644 --- a/.changeset/yellow-forks-knock.md +++ b/.changeset/yellow-forks-knock.md @@ -1,5 +1,6 @@ --- '@backstage/plugin-cost-insights': patch +'@backstage/test-utils': patch --- Making a possibility to hide a trending line in a cost insights plugin diff --git a/packages/test-utils/api-report.md b/packages/test-utils/api-report.md index 38d6a85f5f..1b0aa44fc6 100644 --- a/packages/test-utils/api-report.md +++ b/packages/test-utils/api-report.md @@ -25,6 +25,7 @@ import { JsonObject } from '@backstage/types'; import { JsonValue } from '@backstage/types'; import { Observable } from '@backstage/types'; import { PermissionApi } from '@backstage/plugin-permission-react'; +import { PropsWithChildren } from 'react'; import { ReactElement } from 'react'; import { ReactNode } from 'react'; import { RenderOptions } from '@testing-library/react'; @@ -165,6 +166,11 @@ export class MockPermissionApi implements PermissionApi { ): Promise; } +// @alpha +export const MockPluginProvider: ({ + children, +}: PropsWithChildren<{}>) => JSX.Element; + // @public export class MockStorageApi implements StorageApi { // (undocumented) diff --git a/packages/test-utils/src/testUtils/providers.tsx b/packages/test-utils/src/testUtils/providers.tsx index cf4787099b..8bc4b5122d 100644 --- a/packages/test-utils/src/testUtils/providers.tsx +++ b/packages/test-utils/src/testUtils/providers.tsx @@ -17,6 +17,10 @@ import React, { PropsWithChildren } from 'react'; import { createPlugin, PluginProvider } from '@backstage/core-plugin-api'; +/** + * Mock for PluginProvider to use in unit tests + * @alpha + */ export const MockPluginProvider = ({ children }: PropsWithChildren<{}>) => { type TestInputPluginOptions = {}; type TestPluginOptions = {}; From f766f6f5d511f4c3a5c8e1b087d376c7fdfb3a2f Mon Sep 17 00:00:00 2001 From: Max Morton Date: Thu, 17 Nov 2022 11:06:58 -0800 Subject: [PATCH 19/83] update changeset Signed-off-by: Max Morton --- .changeset/rich-balloons-leave.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/rich-balloons-leave.md b/.changeset/rich-balloons-leave.md index b77524b396..bb6832a681 100644 --- a/.changeset/rich-balloons-leave.md +++ b/.changeset/rich-balloons-leave.md @@ -2,4 +2,4 @@ '@backstage/backend-common': patch --- -Added the ability to understand Job Artifact URLs and raw API URLs to the GitLab integration +Added the ability to understand Job Artifact URLs to the GitLab integration From f1fb8d1d5ec90483b2902078293cfb8e7a8b810b Mon Sep 17 00:00:00 2001 From: Max Morton Date: Thu, 17 Nov 2022 13:55:01 -0800 Subject: [PATCH 20/83] test pathname instead of raw string Signed-off-by: Max Morton --- .../src/reading/GitlabUrlReader.test.ts | 38 +++++-------------- .../src/reading/GitlabUrlReader.ts | 24 ++++++------ 2 files changed, 21 insertions(+), 41 deletions(-) diff --git a/packages/backend-common/src/reading/GitlabUrlReader.test.ts b/packages/backend-common/src/reading/GitlabUrlReader.test.ts index caf82f2f9e..4c612b4350 100644 --- a/packages/backend-common/src/reading/GitlabUrlReader.test.ts +++ b/packages/backend-common/src/reading/GitlabUrlReader.test.ts @@ -585,32 +585,22 @@ describe('GitlabUrlReader', () => { }); it('should fall back to getGitLabFileFetchUrl for blob urls', async () => { await expect( - (gitlabProcessor as any).getGitlabFetchUrl( - 'https://gitlab.com/group/subgroup/project/-/blob/branch/my/path/to/file.yaml', - ), - ).resolves.toEqual( - 'https://gitlab.com/api/v4/projects/12345/repository/files/my%2Fpath%2Fto%2Ffile.yaml/raw?ref=branch', - ); + (gitlabProcessor as any).getGitlabFetchUrl('https://gitlab.com/group/subgroup/project/-/blob/branch/my/path/to/file.yaml'), + ).resolves.toEqual('https://gitlab.com/api/v4/projects/12345/repository/files/my%2Fpath%2Fto%2Ffile.yaml/raw?ref=branch'); }); it('should work for job artifact urls', async () => { await expect( - (gitlabProcessor as any).getGitlabFetchUrl( - 'https://gitlab.com/group/subgroup/project/-/jobs/artifacts/branch/raw/my/path/to/file.yaml?job=myJob', - ), - ).resolves.toEqual( - 'https://gitlab.com/api/v4/projects/12345/jobs/artifacts/branch/raw/my/path/to/file.yaml?job=myJob', - ); + (gitlabProcessor as any).getGitlabFetchUrl('https://gitlab.com/group/subgroup/project/-/jobs/artifacts/branch/raw/my/path/to/file.yaml?job=myJob'), + ).resolves.toEqual('https://gitlab.com/api/v4/projects/12345/jobs/artifacts/branch/raw/my/path/to/file.yaml?job=myJob'); }); it('should fail on unfamiliar or non-Gitlab urls', async () => { await expect( - (gitlabProcessor as any).getGitlabFetchUrl( - 'https://gitlab.com/some/random/endpoint', - ), + (gitlabProcessor as any).getGitlabFetchUrl('https://gitlab.com/some/random/endpoint'), ).rejects.toThrow('Please provide full path to yaml file from GitLab'); }); }); - describe('getGitlabArtfiactFetchUrl', () => { + describe('getGitlabArtifactFetchUrl', () => { beforeEach(() => { worker.use( rest.get( @@ -627,25 +617,17 @@ describe('GitlabUrlReader', () => { }); it('should reject urls that are not for the job artifacts API', async () => { await expect( - (gitlabProcessor as any).getGitlabArtifactFetchUrl( - 'https://gitlab.com/some/url', - ), + (gitlabProcessor as any).getGitlabArtifactFetchUrl(new URL('https://gitlab.com/some/url')) ).rejects.toThrow('Unable to process url as an GitLab artifact'); }); it('should work for job artifact urls', async () => { await expect( - (gitlabProcessor as any).getGitlabFetchUrl( - 'https://gitlab.com/group/subgroup/project/-/jobs/artifacts/branch/raw/my/path/to/file.yaml?job=myJob', - ), - ).resolves.toEqual( - 'https://gitlab.com/api/v4/projects/12345/jobs/artifacts/branch/raw/my/path/to/file.yaml?job=myJob', - ); + (gitlabProcessor as any).getGitlabArtifactFetchUrl(new URL('https://gitlab.com/group/subgroup/project/-/jobs/artifacts/branch/raw/my/path/to/file.yaml?job=myJob')) + ).resolves.toEqual(new URL('https://gitlab.com/api/v4/projects/12345/jobs/artifacts/branch/raw/my/path/to/file.yaml?job=myJob')); }); it('errors in mapping the project ID should be captured', async () => { await expect( - (gitlabProcessor as any).getGitlabFetchUrl( - 'https://gitlab.com/groupA/subgroup/project/-/jobs/artifacts/branch/raw/my/path/to/file.yaml?job=myJob', - ), + (gitlabProcessor as any).getGitlabArtifactFetchUrl(new URL('https://gitlab.com/groupA/subgroup/project/-/jobs/artifacts/branch/raw/my/path/to/file.yaml?job=myJob')) ).rejects.toThrow(/^Unable to translate GitLab artifact URL:/); }); }); diff --git a/packages/backend-common/src/reading/GitlabUrlReader.ts b/packages/backend-common/src/reading/GitlabUrlReader.ts index f54e045857..7b89f00f47 100644 --- a/packages/backend-common/src/reading/GitlabUrlReader.ts +++ b/packages/backend-common/src/reading/GitlabUrlReader.ts @@ -259,8 +259,9 @@ export class GitlabUrlReader implements UrlReader { private async getGitlabFetchUrl(target: string): Promise { // If the target is for a job artifact then go down that path - if (target.includes('/-/jobs/artifacts/')) { - return this.getGitlabArtifactFetchUrl(target).then(value => + const targetUrl = new URL(target); + if (targetUrl.pathname.includes('/-/jobs/artifacts/')) { + return this.getGitlabArtifactFetchUrl(targetUrl).then(value => value.toString(), ); } @@ -272,22 +273,19 @@ export class GitlabUrlReader implements UrlReader { // https://example.com///-/jobs/artifacts//raw/?job= // to urls of the form: // https://example.com/api/v4/projects/:id/jobs/artifacts/:ref_name/raw/*artifact_path?job= - private async getGitlabArtifactFetchUrl(target: string): Promise { - const url = new URL(target); - if (!url.pathname.includes('/-/jobs/artifacts/')) { + private async getGitlabArtifactFetchUrl(target: URL): Promise { + if (!target.pathname.includes('/-/jobs/artifacts/')) { throw new Error('Unable to process url as an GitLab artifact'); } try { - const [namespaceAndProject, ref] = - url.pathname.split('/-/jobs/artifacts/'); - const projectPath = new URL(url); + const [namespaceAndProject, ref] = target.pathname.split('/-/jobs/artifacts/'); + const projectPath = new URL(target); projectPath.pathname = namespaceAndProject; const projectId = await this.resolveProjectToId(projectPath); - const relativePath = getGitLabIntegrationRelativePath( - this.integration.config, - ); - url.pathname = `${relativePath}/api/v4/projects/${projectId}/jobs/artifacts/${ref}`; - return url; + const relativePath = getGitLabIntegrationRelativePath(this.integration.config); + const newUrl = new URL(target); + newUrl.pathname = `${relativePath}/api/v4/projects/${projectId}/jobs/artifacts/${ref}`; + return newUrl; } catch (e) { throw new Error( `Unable to translate GitLab artifact URL: ${target}, ${e}`, From 5e238ed56a8f4091917f95e083d41410e0a0447b Mon Sep 17 00:00:00 2001 From: bnechyporenko Date: Fri, 18 Nov 2022 10:29:09 +0100 Subject: [PATCH 21/83] Incorporated the feedback Signed-off-by: bnechyporenko --- .changeset/gold-yaks-join.md | 6 ++++++ .changeset/yellow-forks-knock.md | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changeset/gold-yaks-join.md diff --git a/.changeset/gold-yaks-join.md b/.changeset/gold-yaks-join.md new file mode 100644 index 0000000000..4502a516cd --- /dev/null +++ b/.changeset/gold-yaks-join.md @@ -0,0 +1,6 @@ +--- +'@backstage/test-utils': patch +--- + +The test util for PluginProvider called MockPluginProvider has been created. It will be handy in the cases when you use +\_\_experimentalConfigure in your plugin diff --git a/.changeset/yellow-forks-knock.md b/.changeset/yellow-forks-knock.md index 6c3d300026..98c4b5b675 100644 --- a/.changeset/yellow-forks-knock.md +++ b/.changeset/yellow-forks-knock.md @@ -1,6 +1,5 @@ --- '@backstage/plugin-cost-insights': patch -'@backstage/test-utils': patch --- Making a possibility to hide a trending line in a cost insights plugin From 7a08bbdb870ef84c6b220baaf9af68754133b7b1 Mon Sep 17 00:00:00 2001 From: bnechyporenko Date: Fri, 18 Nov 2022 10:33:35 +0100 Subject: [PATCH 22/83] Incorporated the feedback Signed-off-by: bnechyporenko --- .changeset/gold-yaks-join.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/gold-yaks-join.md b/.changeset/gold-yaks-join.md index 4502a516cd..e035d97b27 100644 --- a/.changeset/gold-yaks-join.md +++ b/.changeset/gold-yaks-join.md @@ -2,5 +2,5 @@ '@backstage/test-utils': patch --- -The test util for PluginProvider called MockPluginProvider has been created. It will be handy in the cases when you use +The test utilility for PluginProvider called MockPluginProvider has been created. It will be handy in the cases when you use \_\_experimentalConfigure in your plugin From 4638404d76c006e88a1e0650d1fe3e84fc909732 Mon Sep 17 00:00:00 2001 From: bnechyporenko Date: Fri, 18 Nov 2022 10:34:10 +0100 Subject: [PATCH 23/83] Fixed the reviewdog validation Signed-off-by: bnechyporenko --- .changeset/gold-yaks-join.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/gold-yaks-join.md b/.changeset/gold-yaks-join.md index e035d97b27..6871948c81 100644 --- a/.changeset/gold-yaks-join.md +++ b/.changeset/gold-yaks-join.md @@ -2,5 +2,5 @@ '@backstage/test-utils': patch --- -The test utilility for PluginProvider called MockPluginProvider has been created. It will be handy in the cases when you use +The test utility for PluginProvider called MockPluginProvider has been created. It will be handy in the cases when you use \_\_experimentalConfigure in your plugin From 6d0f1d2474a0a23961eb211aadd91a64a1dea17a Mon Sep 17 00:00:00 2001 From: Max Morton Date: Fri, 18 Nov 2022 09:33:07 -0800 Subject: [PATCH 24/83] prettier run Signed-off-by: Max Morton --- .../src/reading/GitlabUrlReader.test.ts | 42 +++++++++++++++---- .../src/reading/GitlabUrlReader.ts | 7 +++- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/packages/backend-common/src/reading/GitlabUrlReader.test.ts b/packages/backend-common/src/reading/GitlabUrlReader.test.ts index 4c612b4350..18f00d9f68 100644 --- a/packages/backend-common/src/reading/GitlabUrlReader.test.ts +++ b/packages/backend-common/src/reading/GitlabUrlReader.test.ts @@ -585,17 +585,27 @@ describe('GitlabUrlReader', () => { }); it('should fall back to getGitLabFileFetchUrl for blob urls', async () => { await expect( - (gitlabProcessor as any).getGitlabFetchUrl('https://gitlab.com/group/subgroup/project/-/blob/branch/my/path/to/file.yaml'), - ).resolves.toEqual('https://gitlab.com/api/v4/projects/12345/repository/files/my%2Fpath%2Fto%2Ffile.yaml/raw?ref=branch'); + (gitlabProcessor as any).getGitlabFetchUrl( + 'https://gitlab.com/group/subgroup/project/-/blob/branch/my/path/to/file.yaml', + ), + ).resolves.toEqual( + 'https://gitlab.com/api/v4/projects/12345/repository/files/my%2Fpath%2Fto%2Ffile.yaml/raw?ref=branch', + ); }); it('should work for job artifact urls', async () => { await expect( - (gitlabProcessor as any).getGitlabFetchUrl('https://gitlab.com/group/subgroup/project/-/jobs/artifacts/branch/raw/my/path/to/file.yaml?job=myJob'), - ).resolves.toEqual('https://gitlab.com/api/v4/projects/12345/jobs/artifacts/branch/raw/my/path/to/file.yaml?job=myJob'); + (gitlabProcessor as any).getGitlabFetchUrl( + 'https://gitlab.com/group/subgroup/project/-/jobs/artifacts/branch/raw/my/path/to/file.yaml?job=myJob', + ), + ).resolves.toEqual( + 'https://gitlab.com/api/v4/projects/12345/jobs/artifacts/branch/raw/my/path/to/file.yaml?job=myJob', + ); }); it('should fail on unfamiliar or non-Gitlab urls', async () => { await expect( - (gitlabProcessor as any).getGitlabFetchUrl('https://gitlab.com/some/random/endpoint'), + (gitlabProcessor as any).getGitlabFetchUrl( + 'https://gitlab.com/some/random/endpoint', + ), ).rejects.toThrow('Please provide full path to yaml file from GitLab'); }); }); @@ -617,17 +627,31 @@ describe('GitlabUrlReader', () => { }); it('should reject urls that are not for the job artifacts API', async () => { await expect( - (gitlabProcessor as any).getGitlabArtifactFetchUrl(new URL('https://gitlab.com/some/url')) + (gitlabProcessor as any).getGitlabArtifactFetchUrl( + new URL('https://gitlab.com/some/url'), + ), ).rejects.toThrow('Unable to process url as an GitLab artifact'); }); it('should work for job artifact urls', async () => { await expect( - (gitlabProcessor as any).getGitlabArtifactFetchUrl(new URL('https://gitlab.com/group/subgroup/project/-/jobs/artifacts/branch/raw/my/path/to/file.yaml?job=myJob')) - ).resolves.toEqual(new URL('https://gitlab.com/api/v4/projects/12345/jobs/artifacts/branch/raw/my/path/to/file.yaml?job=myJob')); + (gitlabProcessor as any).getGitlabArtifactFetchUrl( + new URL( + 'https://gitlab.com/group/subgroup/project/-/jobs/artifacts/branch/raw/my/path/to/file.yaml?job=myJob', + ), + ), + ).resolves.toEqual( + new URL( + 'https://gitlab.com/api/v4/projects/12345/jobs/artifacts/branch/raw/my/path/to/file.yaml?job=myJob', + ), + ); }); it('errors in mapping the project ID should be captured', async () => { await expect( - (gitlabProcessor as any).getGitlabArtifactFetchUrl(new URL('https://gitlab.com/groupA/subgroup/project/-/jobs/artifacts/branch/raw/my/path/to/file.yaml?job=myJob')) + (gitlabProcessor as any).getGitlabArtifactFetchUrl( + new URL( + 'https://gitlab.com/groupA/subgroup/project/-/jobs/artifacts/branch/raw/my/path/to/file.yaml?job=myJob', + ), + ), ).rejects.toThrow(/^Unable to translate GitLab artifact URL:/); }); }); diff --git a/packages/backend-common/src/reading/GitlabUrlReader.ts b/packages/backend-common/src/reading/GitlabUrlReader.ts index 7b89f00f47..522e81cd2f 100644 --- a/packages/backend-common/src/reading/GitlabUrlReader.ts +++ b/packages/backend-common/src/reading/GitlabUrlReader.ts @@ -278,11 +278,14 @@ export class GitlabUrlReader implements UrlReader { throw new Error('Unable to process url as an GitLab artifact'); } try { - const [namespaceAndProject, ref] = target.pathname.split('/-/jobs/artifacts/'); + const [namespaceAndProject, ref] = + target.pathname.split('/-/jobs/artifacts/'); const projectPath = new URL(target); projectPath.pathname = namespaceAndProject; const projectId = await this.resolveProjectToId(projectPath); - const relativePath = getGitLabIntegrationRelativePath(this.integration.config); + const relativePath = getGitLabIntegrationRelativePath( + this.integration.config, + ); const newUrl = new URL(target); newUrl.pathname = `${relativePath}/api/v4/projects/${projectId}/jobs/artifacts/${ref}`; return newUrl; From e905e8e3ddfcd85272bb79988537d7baec34cd45 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 21 Nov 2022 15:33:20 +0100 Subject: [PATCH 25/83] started fixing cost insight deprecations' ' Signed-off-by: Simon --- plugins/cost-insights/src/api/CostInsightsApi.ts | 5 +++-- .../src/components/AlertInsights/AlertDialog.tsx | 3 ++- .../src/components/CostGrowth/CostGrowthIndicator.tsx | 3 ++- .../components/CostInsightsHeader/CostInsightsHeader.tsx | 2 +- .../CostInsightsNavigation/CostInsightsNavigation.tsx | 2 +- .../src/components/CostInsightsPage/CostInsightsPage.tsx | 9 ++++++++- .../CostInsightsTabs/CostInsightsTabs.test.tsx | 2 +- .../src/components/CostInsightsTabs/CostInsightsTabs.tsx | 2 +- .../src/components/CostInsightsTabs/selector.ts | 3 ++- .../CostOverviewCard/CostOverviewBreakdownChart.tsx | 3 ++- .../CostOverviewCard/CostOverviewCard.test.tsx | 2 +- .../src/components/CostOverviewCard/CostOverviewCard.tsx | 7 ++++++- .../components/CostOverviewCard/CostOverviewChart.tsx | 6 ++---- .../components/CostOverviewCard/CostOverviewLegend.tsx | 4 ++-- .../src/components/CostOverviewCard/selector.tsx | 3 ++- .../src/components/MetricSelect/MetricSelect.tsx | 2 +- 16 files changed, 37 insertions(+), 21 deletions(-) diff --git a/plugins/cost-insights/src/api/CostInsightsApi.ts b/plugins/cost-insights/src/api/CostInsightsApi.ts index a7065a04aa..959b40e584 100644 --- a/plugins/cost-insights/src/api/CostInsightsApi.ts +++ b/plugins/cost-insights/src/api/CostInsightsApi.ts @@ -15,14 +15,15 @@ */ import { - Alert, Cost, Entity, Group, Project, Maybe, MetricData, -} from '../types'; +} from '@backstage/plugin-cost-insights-common'; + +import { Alert } from '../types'; import { createApiRef } from '@backstage/core-plugin-api'; /** @public */ diff --git a/plugins/cost-insights/src/components/AlertInsights/AlertDialog.tsx b/plugins/cost-insights/src/components/AlertInsights/AlertDialog.tsx index af976c6d3f..385116e188 100644 --- a/plugins/cost-insights/src/components/AlertInsights/AlertDialog.tsx +++ b/plugins/cost-insights/src/components/AlertInsights/AlertDialog.tsx @@ -28,7 +28,8 @@ import { } from '@material-ui/core'; import { default as CloseIcon } from '@material-ui/icons/Close'; import { useAlertDialogStyles as useStyles } from '../../utils/styles'; -import { Alert, AlertStatus, Maybe } from '../../types'; +import { Alert, AlertStatus } from '../../types'; +import { Maybe } from '@backstage/plugin-cost-insights-common'; import { choose, formOf } from '../../utils/alerts'; const DEFAULT_FORM_ID = 'alert-form'; diff --git a/plugins/cost-insights/src/components/CostGrowth/CostGrowthIndicator.tsx b/plugins/cost-insights/src/components/CostGrowth/CostGrowthIndicator.tsx index 8993504c84..2591fd5a47 100644 --- a/plugins/cost-insights/src/components/CostGrowth/CostGrowthIndicator.tsx +++ b/plugins/cost-insights/src/components/CostGrowth/CostGrowthIndicator.tsx @@ -20,8 +20,9 @@ import { Typography, TypographyProps } from '@material-ui/core'; import { default as ArrowDropUp } from '@material-ui/icons/ArrowDropUp'; import { default as ArrowDropDown } from '@material-ui/icons/ArrowDropDown'; import { growthOf } from '../../utils/change'; -import { ChangeStatistic, GrowthType, Maybe } from '../../types'; +import { GrowthType } from '../../types'; import { useCostGrowthStyles as useStyles } from '../../utils/styles'; +import { ChangeStatistic, Maybe } from '@backstage/plugin-cost-insights-common'; /** @public */ export type CostGrowthIndicatorProps = TypographyProps & { diff --git a/plugins/cost-insights/src/components/CostInsightsHeader/CostInsightsHeader.tsx b/plugins/cost-insights/src/components/CostInsightsHeader/CostInsightsHeader.tsx index 540165d1d9..8e12b7f5dd 100644 --- a/plugins/cost-insights/src/components/CostInsightsHeader/CostInsightsHeader.tsx +++ b/plugins/cost-insights/src/components/CostInsightsHeader/CostInsightsHeader.tsx @@ -18,7 +18,7 @@ import React from 'react'; import { Typography } from '@material-ui/core'; import useAsync from 'react-use/lib/useAsync'; import { useCostInsightsStyles } from '../../utils/styles'; -import { Group } from '../../types'; +import { Group } from '@backstage/plugin-cost-insights-common'; import { identityApiRef, useApi } from '@backstage/core-plugin-api'; function useDisplayName(): string { diff --git a/plugins/cost-insights/src/components/CostInsightsNavigation/CostInsightsNavigation.tsx b/plugins/cost-insights/src/components/CostInsightsNavigation/CostInsightsNavigation.tsx index ad7dea55fd..507016f391 100644 --- a/plugins/cost-insights/src/components/CostInsightsNavigation/CostInsightsNavigation.tsx +++ b/plugins/cost-insights/src/components/CostInsightsNavigation/CostInsightsNavigation.tsx @@ -32,7 +32,7 @@ import { NavigationItem, getDefaultNavigationItems, } from '../../utils/navigation'; -import { Maybe, Product } from '../../types'; +import { Maybe, Product } from '@backstage/plugin-cost-insights-common'; type CostInsightsNavigationProps = { alerts: number; diff --git a/plugins/cost-insights/src/components/CostInsightsPage/CostInsightsPage.tsx b/plugins/cost-insights/src/components/CostInsightsPage/CostInsightsPage.tsx index 00d92f945d..d113f1b8f3 100644 --- a/plugins/cost-insights/src/components/CostInsightsPage/CostInsightsPage.tsx +++ b/plugins/cost-insights/src/components/CostInsightsPage/CostInsightsPage.tsx @@ -48,7 +48,14 @@ import { useLastCompleteBillingDate, useLoading, } from '../../hooks'; -import { Alert, Cost, Maybe, MetricData, Product, Project } from '../../types'; +import { Alert } from '../../types'; +import { + Cost, + Maybe, + MetricData, + Product, + Project, +} from '@backstage/plugin-cost-insights-common'; import { mapLoadingToProps } from './selector'; import { ProjectSelect } from '../ProjectSelect'; import { intervalsOf } from '../../utils/duration'; diff --git a/plugins/cost-insights/src/components/CostInsightsTabs/CostInsightsTabs.test.tsx b/plugins/cost-insights/src/components/CostInsightsTabs/CostInsightsTabs.test.tsx index 2e2131daff..b04f314e73 100644 --- a/plugins/cost-insights/src/components/CostInsightsTabs/CostInsightsTabs.test.tsx +++ b/plugins/cost-insights/src/components/CostInsightsTabs/CostInsightsTabs.test.tsx @@ -17,7 +17,7 @@ import React from 'react'; import { CostInsightsTabs } from './CostInsightsTabs'; import userEvent from '@testing-library/user-event'; -import { Group } from '../../types'; +import { Group } from '@backstage/plugin-cost-insights-common'; import { MockFilterProvider, MockLoadingProvider } from '../../testUtils'; import { renderInTestApp } from '@backstage/test-utils'; diff --git a/plugins/cost-insights/src/components/CostInsightsTabs/CostInsightsTabs.tsx b/plugins/cost-insights/src/components/CostInsightsTabs/CostInsightsTabs.tsx index 935184ee55..152ce56902 100644 --- a/plugins/cost-insights/src/components/CostInsightsTabs/CostInsightsTabs.tsx +++ b/plugins/cost-insights/src/components/CostInsightsTabs/CostInsightsTabs.tsx @@ -18,7 +18,7 @@ import React, { useState } from 'react'; import { Menu, MenuItem, Tab, Tabs, Typography } from '@material-ui/core'; import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; import { mapLoadingToProps, mapFiltersToProps } from './selector'; -import { Group } from '../../types'; +import { Group } from '@backstage/plugin-cost-insights-common'; import { useFilters, useLoading } from '../../hooks'; import { useCostInsightsTabsStyles as useStyles } from '../../utils/styles'; diff --git a/plugins/cost-insights/src/components/CostInsightsTabs/selector.ts b/plugins/cost-insights/src/components/CostInsightsTabs/selector.ts index 6309016c85..7e19deb301 100644 --- a/plugins/cost-insights/src/components/CostInsightsTabs/selector.ts +++ b/plugins/cost-insights/src/components/CostInsightsTabs/selector.ts @@ -16,7 +16,8 @@ import { MapFiltersToProps } from '../../hooks/useFilters'; import { MapLoadingToProps } from '../../hooks/useLoading'; -import { Group, PageFilters } from '../../types'; +import { PageFilters } from '../../types'; +import { Group } from '@backstage/plugin-cost-insights-common'; import { getResetStateWithoutInitial } from '../../utils/loading'; type CostInsightsTabsFilterProps = PageFilters & { diff --git a/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewBreakdownChart.tsx b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewBreakdownChart.tsx index 962dc6b332..6433ab472c 100644 --- a/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewBreakdownChart.tsx +++ b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewBreakdownChart.tsx @@ -32,7 +32,8 @@ import { ResponsiveContainer, CartesianGrid, } from 'recharts'; -import { Cost, DEFAULT_DATE_FORMAT, CostInsightsTheme } from '../../types'; +import { DEFAULT_DATE_FORMAT, CostInsightsTheme } from '../../types'; +import { Cost } from '@backstage/plugin-cost-insights-common'; import { BarChartTooltip as Tooltip, BarChartTooltipItem as TooltipItem, diff --git a/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewCard.test.tsx b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewCard.test.tsx index e3de9593d9..91c599e407 100644 --- a/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewCard.test.tsx +++ b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewCard.test.tsx @@ -17,7 +17,7 @@ import React from 'react'; import { fireEvent } from '@testing-library/react'; import { renderInTestApp } from '@backstage/test-utils'; import { CostOverviewCard } from './CostOverviewCard'; -import { Cost } from '../../types'; +import { Cost } from '@backstage/plugin-cost-insights-common'; import { changeOf, getGroupedProducts, diff --git a/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewCard.tsx b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewCard.tsx index 9eb5f1e190..c816da97ed 100644 --- a/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewCard.tsx +++ b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewCard.tsx @@ -34,7 +34,12 @@ import { useConfig, useFilters } from '../../hooks'; import { mapFiltersToProps } from './selector'; import { DefaultNavigation } from '../../utils/navigation'; import { findAlways } from '../../utils/assert'; -import { Cost, CostInsightsTheme, Maybe, MetricData } from '../../types'; +import { CostInsightsTheme } from '../../types'; +import { + Cost, + Maybe, + MetricData, +} from '@backstage/plugin-cost-insights-common'; import { useOverviewTabsStyles } from '../../utils/styles'; import { ScrollAnchor } from '../../utils/scroll'; diff --git a/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewChart.tsx b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewChart.tsx index 1c58bf58e6..e5b0c59684 100644 --- a/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewChart.tsx +++ b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewChart.tsx @@ -26,15 +26,13 @@ import { Line, ResponsiveContainer, } from 'recharts'; +import { ChartData, DEFAULT_DATE_FORMAT, CostInsightsTheme } from '../../types'; import { - ChartData, Cost, - DEFAULT_DATE_FORMAT, Maybe, Metric, MetricData, - CostInsightsTheme, -} from '../../types'; +} from '@backstage/plugin-cost-insights-common'; import { BarChartTooltip as Tooltip, BarChartTooltipItem as TooltipItem, diff --git a/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewLegend.tsx b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewLegend.tsx index 2df80f4780..d823c54691 100644 --- a/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewLegend.tsx +++ b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewLegend.tsx @@ -17,13 +17,13 @@ import React, { PropsWithChildren } from 'react'; import { Box, useTheme } from '@material-ui/core'; import { LegendItem } from '../LegendItem'; +import { CostInsightsTheme } from '../../types'; import { - CostInsightsTheme, MetricData, Maybe, Cost, Metric, -} from '../../types'; +} from '@backstage/plugin-cost-insights-common'; import { useLastCompleteBillingDate, useFilters } from '../../hooks'; import { getComparedChange, choose } from '../../utils/change'; import { mapFiltersToProps } from './selector'; diff --git a/plugins/cost-insights/src/components/CostOverviewCard/selector.tsx b/plugins/cost-insights/src/components/CostOverviewCard/selector.tsx index d0f7cb76d9..55ad6df69e 100644 --- a/plugins/cost-insights/src/components/CostOverviewCard/selector.tsx +++ b/plugins/cost-insights/src/components/CostOverviewCard/selector.tsx @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Duration, Maybe, PageFilters } from '../../types'; +import { Duration, PageFilters } from '../../types'; +import { Maybe } from '@backstage/plugin-cost-insights-common'; import { MapFiltersToProps } from '../../hooks/useFilters'; type CostOverviewFilterProps = PageFilters & { diff --git a/plugins/cost-insights/src/components/MetricSelect/MetricSelect.tsx b/plugins/cost-insights/src/components/MetricSelect/MetricSelect.tsx index 090444f025..fd534eb8f0 100644 --- a/plugins/cost-insights/src/components/MetricSelect/MetricSelect.tsx +++ b/plugins/cost-insights/src/components/MetricSelect/MetricSelect.tsx @@ -16,7 +16,7 @@ import React from 'react'; import { InputLabel, FormControl, Select, MenuItem } from '@material-ui/core'; -import { Maybe, Metric } from '../../types'; +import { Maybe, Metric } from '@backstage/plugin-cost-insights-common'; import { useSelectStyles as useStyles } from '../../utils/styles'; export type MetricSelectProps = { From 46c874b93ea3dd8931c89f26e9bd5bac8560e8d7 Mon Sep 17 00:00:00 2001 From: aaron Date: Mon, 21 Nov 2022 09:48:32 -0600 Subject: [PATCH 26/83] Update accept.txt adding 'allowlist' and 'allowlisted' to acceptable terms Signed-off-by: aaron --- .github/vale/Vocab/Backstage/accept.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/vale/Vocab/Backstage/accept.txt b/.github/vale/Vocab/Backstage/accept.txt index f2b3ac0b09..d3157f519c 100644 --- a/.github/vale/Vocab/Backstage/accept.txt +++ b/.github/vale/Vocab/Backstage/accept.txt @@ -409,3 +409,4 @@ Zolotusky zoomable zsh Lainfiesta +allowlisted From 9e4fbf0ff491648b4d4b2360450e5a4fb063eb9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?MALIN=20WID=C3=88N?= Date: Mon, 21 Nov 2022 17:20:14 +0100 Subject: [PATCH 27/83] Remove some deprecations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: MALIN WIDÈN --- .../src/scaffolder/actions/builtin/createBuiltinActions.ts | 5 ----- .../src/scaffolder/actions/builtin/publish/index.ts | 1 - .../components/TemplateEditorPage/DryRunContext.test.tsx | 4 ++-- .../src/components/TemplateEditorPage/DryRunContext.tsx | 6 +++--- .../DryRunResults/DryRunResultsView.test.tsx | 3 ++- 5 files changed, 7 insertions(+), 12 deletions(-) diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts index e388a70f00..6f4543673f 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts @@ -45,7 +45,6 @@ import { } from './github'; import { createPublishAzureAction, - createPublishBitbucketAction, createPublishBitbucketCloudAction, createPublishBitbucketServerAction, createPublishGerritAction, @@ -142,10 +141,6 @@ export const createBuiltinActions = ( createPublishGitlabMergeRequestAction({ integrations, }), - createPublishBitbucketAction({ - integrations, - config, - }), createPublishBitbucketCloudAction({ integrations, config, diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/index.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/index.ts index a8a40ab1df..37969c18c0 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/index.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/index.ts @@ -15,7 +15,6 @@ */ export { createPublishAzureAction } from './azure'; -export { createPublishBitbucketAction } from './bitbucket'; export { createPublishBitbucketCloudAction } from './bitbucketCloud'; export { createPublishBitbucketServerAction } from './bitbucketServer'; export { createPublishGerritAction } from './gerrit'; diff --git a/plugins/scaffolder/src/components/TemplateEditorPage/DryRunContext.test.tsx b/plugins/scaffolder/src/components/TemplateEditorPage/DryRunContext.test.tsx index 184118914a..91fb3d934f 100644 --- a/plugins/scaffolder/src/components/TemplateEditorPage/DryRunContext.test.tsx +++ b/plugins/scaffolder/src/components/TemplateEditorPage/DryRunContext.test.tsx @@ -25,7 +25,7 @@ describe('base64EncodeContent', () => { it('encodes text files', () => { expect(base64EncodeContent('abc')).toBe('YWJj'); expect(base64EncodeContent('abc'.repeat(1000000))).toBe( - btoa(''), + Buffer.from('').toString('base64'), ); }); @@ -38,7 +38,7 @@ describe('base64EncodeContent', () => { ); // Triggers size check expect(base64EncodeContent('😅'.repeat(1000000))).toBe( - btoa(''), + Buffer.from('').toString('base64'), ); }); }); diff --git a/plugins/scaffolder/src/components/TemplateEditorPage/DryRunContext.tsx b/plugins/scaffolder/src/components/TemplateEditorPage/DryRunContext.tsx index b592e3cecd..17e077e47c 100644 --- a/plugins/scaffolder/src/components/TemplateEditorPage/DryRunContext.tsx +++ b/plugins/scaffolder/src/components/TemplateEditorPage/DryRunContext.tsx @@ -59,11 +59,11 @@ interface DryRunProviderProps { export function base64EncodeContent(content: string): string { if (content.length > MAX_CONTENT_SIZE) { - return btoa(''); + return Buffer.from('').toString('base64'); } try { - return btoa(content); + return Buffer.from(content).toString('base64'); } catch { const decoder = new TextEncoder(); const buffer = decoder.encode(content); @@ -74,7 +74,7 @@ export function base64EncodeContent(content: string): string { String.fromCharCode(...buffer.slice(offset, offset + CHUNK_SIZE)), ); } - return btoa(chunks.join('')); + return Buffer.from(chunks.join('')).toString('base64'); } } diff --git a/plugins/scaffolder/src/components/TemplateEditorPage/DryRunResults/DryRunResultsView.test.tsx b/plugins/scaffolder/src/components/TemplateEditorPage/DryRunResults/DryRunResultsView.test.tsx index bc6b5d8f6f..106ee0379f 100644 --- a/plugins/scaffolder/src/components/TemplateEditorPage/DryRunResults/DryRunResultsView.test.tsx +++ b/plugins/scaffolder/src/components/TemplateEditorPage/DryRunResults/DryRunResultsView.test.tsx @@ -58,7 +58,8 @@ describe('DryRunResultsView', () => { directoryContents: [ { path: 'foo.txt', - base64Content: btoa('Foo Content'), + base64Content: + Buffer.from('Foo Content').toString('base64'), executable: false, }, ], From 5b73093c42f04a65556b8a0c39fd3412f8daa57d Mon Sep 17 00:00:00 2001 From: ch-enfuse Date: Mon, 21 Nov 2022 10:23:24 -0800 Subject: [PATCH 28/83] Add Azure Spring Apps Plugin to marketplace. Added azure-spring-apps.yml for plugin to be in the marketplace Signed-off-by: ch-enfuse --- microsite/data/plugins/azure-spring-apps.yml | 10 ++++++++++ microsite/static/img/enfuse.png | Bin 0 -> 144895 bytes 2 files changed, 10 insertions(+) create mode 100644 microsite/data/plugins/azure-spring-apps.yml create mode 100644 microsite/static/img/enfuse.png diff --git a/microsite/data/plugins/azure-spring-apps.yml b/microsite/data/plugins/azure-spring-apps.yml new file mode 100644 index 0000000000..cefb0e2824 --- /dev/null +++ b/microsite/data/plugins/azure-spring-apps.yml @@ -0,0 +1,10 @@ +--- +title: 'Azure Spring Apps' +author: Enfuse +authorUrl: https://enfuse.io/ +category: Discovery +description: Easily view your Azure Spring Apps service resources +documentation: https://github.com/enfuse/asae-backstage-plugin/blob/main/README.md +iconUrl: img/azure-spring-apps.png +npmPackageName: '@enfuse/plugin-azure-spring-apps' +addedDate: '2022-11-21' diff --git a/microsite/static/img/enfuse.png b/microsite/static/img/enfuse.png new file mode 100644 index 0000000000000000000000000000000000000000..42124a4a246abc25606805d591f6d2b5cc1b94ce GIT binary patch literal 144895 zcmcF~cQ{*b__sumgc31IYXm{4)~r!QVkT;Dtv#ZYT9qobsZETwRP9Y`rS>YND5|Qd ztwm`ON^Mo%e1Grn@AtnqS8|<`bIx_nb3e~LKKJLoPrQ+V&IRZtC=CtG1sqn>goXx4 z-38Ks|Jwv#(s)hXKzy*){xmeqyZ`+FJf_(d@Gj*w z%QpT#>V8#q|E>WXL41Q(5;-_OzaC7W#Kl`T2?Ij5*0*lpR}WP)%s;`Wju4Ww>4@4} z*+X~bE+wm~_59D~*8l&_h2n9yktMe@?qpT&|JT$0yG{=;cj8G`JbqX1MB;jqc5xVY zV!jsjShG7vc{)>4WW8t!npZj=|7q@Dll$@nie!T8krQG0xja+7eq zX#DuE39{6skTy?}=zqua>qqbIao?rhd``z8WwRD#p zHKBMF91~L2i@>!beY(fhdl74Z36tRw`6bXPdSvCAc*zLBM2P~Q>)I%9qFcH zF6ywm-~7+zchbFZ9Ru>;Ro(`pqg$Mn4?T6FsbjdjYn*<>HTyUTNxkt4nT+vYqD#EH z1~Nts&I`B&$O5aH-*(1#m4+5)0A7?Kd=RZEHJFfmgC5FQjYRfWI1vOa3pt$FwE~EuFGR5<=X1h#3$AN9j4!;eAY*xQ(zFf#Tan>=Y35l@aAx zGzAPyU^Ahp8J^rOLj!I8arR}Wm!bM+&4_fkE$lFwKHLxz20E`ZfsVuywmXE5|- z1wdj1F@hG#_5|Ye> z4@|-lKn%Eaf9*J_Jq#yRZrC=Wq$|I;6WMAMYcLLsR zrc++>#)3ng-a0u*V+kV&iHl-sFtbF13lF0sBl^(7LZmjlxTtXnT28+hIx)Xc@7mkuUv#2JQIOFS4JTWG=jauV}PyX>s8jRJX)=Ds^ZrOJSwq}LxlAG_sph7T8C1xZqFh5EK05{v3;wÐ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

QBQ5Ki(#e!yT05b@be(Nb)(I0Q@$zT*sK zIm^EsxUH5_(oyOGagt1@VTh|Uj$~B7Vd~((nq@*}4e_}=HQqORyt1;hle4_M`%}^& zFYIu2&m|;ycZfW+*kb+lC~HT0S+M$-pf7|teof!0(u00x}t z6L%CIqb$B4y>0|{GE3;Uli-kTEcrT70fOnnWg%bKw3uELX6Xi$&(_OgOCA3#VY^=Y z&NkZGO4&}fw6%2J?mRg=O0|EyGx}TY?|QYN>Oaq;z3Cp&RF%L&`gfZ93-tmHCYmMS zL!@|xz!mLq`d$gZOSrNDQs{sQ6dV2y1O`RMG4MA;Fq{ivf$7+#*T~n{-a9k2H%wUH zhHF4|Le_<^mtK%Aoza`{`dzJW@Aa|k-_{EM`SSV^nY=b!O`6y_xgBzIy}4#Be3Nye z`1XYf-HEc&%cFHpg<6wEmWDF=Y=|LUT4`3LNM=qhSWkcK5P%K^hQX8_Eht=ZP#+w$ z0C5Ye9@st)oT)6sz=X+X`6Mq!aXiI8Q5T6<*G0sK>t%kHs4scu^bD9u zLyrWr%D`+`Q37}o0fEBp?;7&k-@`ySTsX4hskP)nx*poWECFH`lquMwb^Fmc=j*F= z_i}TFHxveHy~h?_hMb?C{{2mjd%F+z-*3$JpAcH-JO~zdAz>FK_%onfrf!LL+$G<;Js?*Qk5N`kFa!>>F=kK) z${>)R5lakE7F9V~mNOj~G@II?r4ow_cYz~8{SvrQ&4)yFP33Jz@rg3;8t>X`HTK;% zRsL@E_g613pC6^JjUGSnJ-9o=Cw;ZSYg*1PORkFireZX5G<|&QdK7a^aF)-Pva+h6 zl54tsVx?FyULQC&icVaSi?SUdP4bbXTYTOK1{1M@K;1V@*j@<{T`bmz5m}S~)M8iP zO3=tx7fYKr={zYv_Kf;Ue*bZ5W^-_K%KO^=8asQNT>E)DDls(on9vydXN8oidK{>D zbBb>WUw0K9UjdDVAw_}0BZAL3z$BWOK8Xt$I6NJU0%IxQMJLX;6iw7A+L3eT`*|T% z-A%Do;%E~%^?Q(xb+T|ke>eLu%~}BK&zYS~BqdHPPmnCje@c#h%RmRsXZE`rU!4ef@A68|jwj*4=VIu*#-c}yg*Flx!2zg3LRm?l1QV>4 z9$OWKOOd3meBi3;OVt`-qJt{qShuWjal$tM3_yJqh@vt4Dd3|1g~+OLclX33z1Q!X zIv@R5J-ADrY$Si`_*7RyY3gb@+4@FJ8JAWkGA72t&f9B4|BjL*^H#Rq3otH3nqo@0 zIFK#^3dV_1Du`e!BZmX{(+Z-|rV~Q)7$=d7l_jaURl1*Fcokf|wC33~fmi9G&e&S@^2PHrez$L-%}Pp( zOCGJ$MyC7vGTDvSvt{VCIHH5;;()!c-iE(>)l$CA2UtugWQ@tyieX6&%x`tuidJF6 zGt1JEio>(SGznFRUL%Ca7KifU)d8bE2h@QL1ERi;0aF@eah;B@$Kk4nZ1QvsX~7_8 zmy{t|d%i-d?S6bfey)=r8oIZ))~o5_&~9+2B3?YG9DeN}VrqV1y=UUexCz|6fy5i4UeiYa zBSf8maOHFwT=ZdoTwFd>?OiyK{kQC40z>!0+o&)U)M3G6E&~gM=n5IXg6}L3a%w!vV^Xw|4JGU8z`{ge1SXIA}&#CbZz8+tl zGfSE*m$Z9)HtVf=d{UjN_V;wCJfAP*)HwgwvX$9A{R2(@0bh5mN~GXA7`#`KDWdn( zRhm6g{5rMgbZ1!bptsf`H0{y$#)X?l0V9T>zOXB_PLds_F}iSOfk;h6YPP!o%)rJx z``6{B>dp1j_0u1x`-vGBzlDaKp7!teuTUSqUR^xL*SP68E3x5ceKGOXlO{fyHgz1i zgwEZBt>3P4%5P@`yEer>+-v={h{CB)&0?B^kfuy_DI`8m>7ao+Vvn7HeiYiDy zX`ITT8WD8S%?Y{N7Lan_lAZ5ZVKi__!mY=t=ctySM^#|jO_gF`!1kdB?oTjU*Gua@77@LA3nhn0<}mn1yJ$-8_%}M9~TH_2=g~*Y(~>@iKLedw5Q0 zmgNcd@@XdK!py}@BBsS0@d8UJ@9dx$!2HUmnBEbm+NmqjjN0apiDvz;qKi#Dv)O}z z(M|EmimsfiHr1hAbe_PJZyt+0pI=Vq#U8PX|{MdIp|5Iy!Hr%c9Z#Acs^OBszuZk*M zB%Hkx0f1`@0;AAHGy+8F;6;_C*LCH1Va{uu zMJNHkoOHl96#MT8Z)wgMAHB^i1Uc%&0iz0w1-0oEwKXZ`5EQ;>*R*~*aVSzH2K59E zWfh?-(izcoYntLjnfJ+CD(>r=dJP~u1})A9nmdk= zhhJg}B8?;B`z7YC6tuTkqRmb-oiqnV`lK#&n2wmi2v81$xKnM_>v*0k1}`>fBrX&R zug~(a8}iNcG&IV8YR++grJs7|js(k$P;h;TcN4d%c^en0>$Yv4txev`kU!II_Gh!* zUggCSx9Oj(eA55H#C-LE=G}OcQj^aUpZE}!zrG_Wbcww2%0)ZWZZGerG&^hnXrGF| zBw|5`?=*mlz36ugjvn>1n2k7vM)XMt^uM|!8+(WZ^yT$Q(1D{pqo%G1NVPPUJyUg$ z+;eYirG7$X^KxHyo$lt_b)TM{9IYHIc|P*@t?LYZ)2ZUL+v3e%uR6GjSSH>VPUIjj z+of6SMm73ePNyl=ZTnKJ3#7vjj0pOGq?K1+!;R2=x!2eimVL_mcw@eBl9GW9g@MWpn1!YWia<@Li&Ba?h)OFipVy51_ zu$e8ql;`xUlVvTHzA2+=hsqe)*x7Zf+IFk9pX`yy9{b~>{9&hi8KPr(*YZP_TsPdW zdP3ca2oP8cR1~eL0ZdBB2gh|vC4#urk2ZkpP}z8Erv8*^i1Jd;H?QwKwFvO+UEh+=csXYwRrbn3g?5KAP9|3*JbWfI260&mP(bn}BcW7gpUr8|@>UJ2?t$qk5NH>@p;F#RBd$9`)!fI@Hz>Izj*>uI?z3 zzzU0kwVBhtBlN7hwszr_Htz5X&FOVzKuZ7ost~hA`4amPSy9HfXv!LH+rUC#*%{ovDTG&o>>V zGdY6v=iN0r=4}e~?<9FCYBK6KFF$B)Rh_S~nCPEgJ$)SVh^pxOM-yYu@^7k~9$s1f~%m+~C5EMgpVXNkkB(5?d#FMwt5bw5Awk0sRJ3?y#+jtbQX(R_^xq z-%{J(Yjuwp7jw6}wxgnhvoZMax;{O@MFxmB9ZVUA4M&Ct*~G*@!9(8{rFOP@)l5Dg zaJx8`TAMmnV`!J(85j`ichmE{W9~ll$$G)QP;xA_NMteGb-$6XDx<#YO4?kEt8kyW zco1vlTfbYq1^|OXK}xpuNJ>QS2vB^>9K`N0GKO;UHC%khv1_`-z_G(;8V!d6*a&@h zfc@dlh!-uzKD7lcZYY>Ltbhz4$w{$7l0JEH?5!KY%rw|q+Df0HMYFN=ho#RL-Cpez z);|tz4}QjbbT)62i}y$SsYKyM#xlurAph~dzi!`77pE1LCmy%n^mr%0h;ocbc+e&w zn-0JG1X&Wz%nXUPR_{#((=qjT76?)}l%2|{NiLvJ5MTcG=Fwj&H1rk_69}f3kFw(P zpMrYxN|5PU`v!|>HX}#UjOTrYi#eO4YyH#t`T1dgmrlsj>y*)xQ@>zR(954C{8GG1 zu}O)(6DL(o zQYhrA?N%O*n6ZAcr~5hPwqVc%zTkRm4C~AEneb)D&Nj-MtIav1g!Z-CF>k|aM_h>H3($Z4lxk7DM zi0`Avgq``}SfJkVSOKh-o@KT-!YyYAF55^3~Mc--+EG1JUYgkgp^1E)F{bA`oe!j`CdcMA}=7o0P#7uw>;I{e?6;xy+t*V9f8uOrq2 zC zcU=>Y#OO+f+s0T9=Xtwpe@~3% zul`Hi`SSV_*{b;!S>fZ%b@?3YC!c~i%{91gxLAjyM6Z^9GAYulXDjG4U^ixZY?Tna z8nP<+hP_++;`w(TCeTwb{c{?s8X7thPLG_or?^FRQ{Nn+hTj=8#O85A z5s?)G)`av%g-H}e8uL5_(>(!_*tX)PG5ohoaD`6$0r@sdCzKz6d>&r!hKaHcq(Q!zpgCr=MQG^y9Q-)x?CVfybE6jY#3JiphgVUeY z3tXWEn1bfUyvNO7%L2=3 zWyMKew=0{H(=uh%A38~;-xjwj!Cm#hX^5LOI2+SZ>%q_*U@{SiIv($?j&2wl7^?o=^v(}GS<9f-G5_sN z3-PzcW1=`4#9qu%0K(?t+<<3f8lj3_L@X%2Q-%%$U`$BQy!&1y7Q56_tFUeO9>5eA z43)(>io#439~8jj@B;CHI_Vh+IpV(Y)|CvfqQtN9$S9PcmY*4}&Ew~Icwr^vm#zse zl_*}uGgpxQ-&;_xzrD2SPz?<@nSW?0T5C~jDF3teFPU8IyW8^KHUF7sD%bNy-V@!4 zs}tH9?0sJ{Be)WgX1XhPQMd2TgQ7GfrL@gpu9r&s^4=Nr@fx2BF`nDJ1nNF9@hnAY z)E9Fl@GH&LXlBd}ABDGAev`STZ?_10l{ zR~*$uB!gaGXB00SCevdCO(w}b(viz!eD6CEg400WOxhJgE`?7hF|r*IJZ^cD^J zB%CZzm4i4UKolGqsKYu~h(-gG)+yIP99x6$HP`mgt&vUx;plL83kKw8Unlk0^~P4~ zP9>FK|AUj!;oXei-D+pM{LMc_H&;DcyOe&-4t$Y%{royJH%kNW6q9xHOoIE1BB`vx z%AwKMBI3HJOK(2v#T2mvG&nq@VW_7!hU^X}nNtpgP=>3CoB2=Sk&^`=ViRx8!MOObJcio}mBK;L*xlSGs@I<7gX#Vv-R`vX<^W0Zlt_UmAHWdy!r}CmvR|eEa)469;wPDO1<(*?jp$B?{=vFteD9+#G1{;L57Vi!WJP zpP)Lge_(CtGl6ILD7cqg`ETtgUCr$%qi{JsH5hv8av#Mv=Rqr!@nR@3)@wjgL zJovHlY^TX$vU;;+zUG?bf{pi^8PAWBDXPH-dx?^2$A3toW2zyiKPs;3y|eQ04fwT( zQg#J_kkz=9*;q$lCvn0)Bc&lm>UbC*7QV+!5HTwaV|Iu`&J zO#?{))Af#we3@c}1DN1M7+BK)4WNTpikpYTxe8VN>c^L)F7L09b0#u|Czf+alcJLL zFZuKDr`QLzE6ptMx$gSPr;=_^nuohWH2E7EtE79%q}7Zs=FKP=Yu@DC{4698*{&bl5Y{E!)vNx`+FO;YX45CSpN8Ue87-dHAs$!`M~cp zNZd?jG#Uj2td+14KwK3lltlsT|8R7jfoyhfp9msVBBHfL1fgoRR+R=Z5^AJYX=|32 zm`{zO_NMmivej19-kTb&YK+!aT6@>#z2ATGA)j-fbDwivzjeWp;Iw7}+n(aioD=Jj zZT`X^>rgoAAeYx&zhnLh76U+l9VDg2CzK5GgglD8I9=5#I+enFv?m5_mmOPD<|tDu zV=MMV@p81a)%W83WT<-?&=Q}l?wl<2dEM2DmE?Y19JE1p^_C|YUCCb-p=~sHwH>YeSK5Sk+?}N9IR!)ODmw9cq4+I8Kx~4Qo3wFc{eaIPu=jYJ($i zE*>xSX876N8wrTwH5|!&NF~gS`CFi&loo*+tFR*Sie z=w}5-SMX{0Y`g@HE*#7j41m=Si`w9~qJp7Ss$lEbbZVwI#3AKPvUh_6FY>eJcH9f2 z_=vXy2SZCkE5(4M!?yflzc+EKWx7RT*bWrte1xRo^fC`&z`oezZ3A)lX4lde3Gx0EHJP*_pJO zJT7xQ1+ciCe%sdbX(PX*&e0(wTAd7f9-hj~xKHVFLO9j^+iyb(0en0efrq&V4{9SJ zmg(N1|7&As4dr-Z94P4BhMvWJHXDPr>&SSdadwjekX}xQt?Y& zU#|WGG0wsPI)yH@i#_Zip4n2Ya9>nZ<6G*IEOoJG&Wk%&I>fPrrdGYQEi$LW;(zl&wCK5i?vhR!?1ZwGeRJTSq++Uq8 zmyE5sxB&;&`R`(}jI-sa?p~gywhe!<(6va1iePASFGCC`0s%o_A^-vk;*IwgXO0X+ zbD!PpytH6cOyX<&E;8inow2rweWn(t6rWw(;5E2>Zf4U%vMEZGMELuMMtNT-jB{Zz zH2v0Y1{~>w)ki@QbppN#ae7MOR%pj03Kq)fNLJ`z7X}ut`zce&2v7u#VlCmH#F6?| zTd8k>7KXf5wP-75=CilaKakoh_M}9|%xO6G`dhN%E5)*Fh3R#(Vl)RY?S{SLhcfkw zwBE!wPN~joCw$mvW7dRd3JBl9LzF7}fs#u3nNXWj61)w7*@du6x~}0WJEw*VjQk6) z;ky2okiJZ;^F-vSIBumQ!upn-@=FO#A)%so5+Sz{izQ`-5yhHS(u3m$Z;Jt(si^@l z!uuSrP9A3X9Hjm~@zp-6vvt?k=W^%O(5d)sQ~U^+YIs5-210`at7_mPB7&9am9cOE zxT)HL+R?`h>1|r(EO9#1g-~?OkIbOJK;1Z$+|?`r0x#|h*Z@@+7-Bt7L!EsGB_xob zr(DFY9JD0twYB<|JlVa{K5{(JIcf`tKNRj=%ukZ%iyLIemsXlfxQBl}4jT#?D^9QL z3`u5_(z$N+T^$}_VaN`R1@{Gi$gPY=Oreq1pk^aV*INmZu3cRgs7S7=JlGDyo=&Tg zC<~8puYX`rAi+GdKg;%GK|-9!*FXOq5M`8E3e>LuShj{-!FP%~O{P^>?JlhQysW<4 zEbHaw4qS47=jQ*IDVz_O+4x=To%NS&Y~8ZY{jy^jBW&=QR~HNkfXB1Kgz)~z2(%@> zi4XnghA-Eiy5x2*vxHt67*|22P-0T&0t>+jQs&W25LIH4KROenq#PI);A+4~xC4p& zrmIG*p#5rts9r4|AfN27AI*{5WoCH*Qo4K3Xe}q_j{MH9Wors)c$tmo=V|k}=Z7Iz z0h`V*g#i>{5(bZrNJRnBU*l9!1J@lH6DPJtOEMSQKs=|;eRaThj56ok8g_2;pf zINgZS?bB;}#RW$SH;^$(BxY2Xq_4XJD86w`eZRp-L1{5z4_GXgXX$ASf#^NIa7@ghK&=jKZMz z3I6eviI}7cqPeE)gWi?sY~WtGCnqPTD1UNtDerr{yEH!gPSJbJjAy7!^q>8!u%T&Q z>%tvZy~VbPlcGXKfoe)rB=p5|(!OUf@>5_z=sQRUi5_LBtTj<2VE!W)Bp^WJ^~iF8 z6>1QI|KT4V7{eDx3G5ER_^dWvCg?a=0D7~)S(ifW>W z7UON=dT{4O6(4Ip6n{;t|7`O5ZO#GE1PqKO-nm2S^#j1!j~Re?Ca5>|kbA1iriaL( zP6*8Wj9kPOWyZxti0i|hRbb8<5-#vI=;i(>@HjvVT*75}S7_lFfCSC8u|iYwCPI^O z(9Z=LPy^xqNYQShy$Z3bY&aLEJYM(6?D4yIEsC#>&&VSqBWr$_t)fp_TkgshjE+w3 z`m{XU^!`u%yiDysRngFvHxk48K}C5ftdQUr^_qO_ze*NGsqV9X$I_E>R_tr&wD7hoUG z;P%_uzep5}I`x=*J3lw^Jm?Km9->gAkO0b8O_ZgR=k4zDM_;U@(x2^s!PLuY!5xOw z5qKu$AJNzalY}CouyCBdIda7yUBrIWgov(};Jaw^~=eANDb?)+CZ^LMl*`(EvRabMVx_6428P8uB@QlBi)&wPCnDiW7)^7hm zgjs&CPbuI-@Lh2!y-i6pH%QfjA(-FdS)^Ig-@`3#)ZxTUyYHR1bQPew)G?%P|DcnJ z`&C3c&_Gs{)~9S7HbFSvvJ3-z8OYX~-7_+XvoC!4%wY^yE;Udb^hYd)fq~JCC*#B8 zcVb2vWvAymI}0=KCoiUg?$)*oV~DxJ$y|S9ZmOE{lIY@&KDH(nMb6ePs4U;y$r_eN z?4?ZL)6nS8lc7Z)Dh}_Df=m{G= z|8-7!%zk)vxv?~0v`DUxEwkD5m^!R_v_IN?LTZuYUUiKf`t~d+PTB%Dt$fGHo1dz^ zou4U)67VrGUiZ{ds*C_rMbM~&_Zaj@EaE(Wri6FY^w*O-jXX8Apw1YVo5Dy- z;x|iQwZYS_SeAP?7mVm^)aT#S%_D>{)Ci0@=|+tfJAH0IKgELDgs?zS8AwY>BMgLE zoJ@OIp<()M6TRp5Qemv>*!TA6+3@;i;{1i}q2lSD(d9os#q(4@@9q7)W}Rz$wBP>n zl5W2!5T;&Ng4f+)xO%wMlR&b`E_}-nAV(eS+&P7DM96?-Uwd@>Xf*LHsCV29VZ@!~ z)1L(hEvv%?CMhM$65|;1=#aeepZNNby2xGeD`}iwWn12QezG36 z)oUcyJKig&(C_6oD<$*aLH$X|_aFQM71{bfvIZW51x0s4+bnK`b7XVsGSyh>V*^4g z3*a&f;W7jpI3Fhzg{XRpu_S6))UuYY=A?ha)_wE^r>SFdr_+l)C&!6xcS=^J!Lthk5DcU zM&mH^+g9B=kS*p`qNjRrhtp&mPyBJ+r@Sdpf`tDUNvLaZnS~YJ9hYd5P|=awKqxdZ zdjwQ|uiRgpb&g;9o}Go|IJHc3au14$T`OK9)w}Z?R)0urPI)+XYfPn>^4C>XAq{o@ z)L-FPbAgHpI4qM>07Q$?2v(-+)e{O01V>rI)%^nl5-5AIs_lJ|K@-rlQmDgDUKk$}7Ufw`l8KZAU?cIu=gOo@|nSxv}aPe@BGXIl@7^bL3q;v}rIMw&ufg`it- zr(|&%P56sTM(h!ubAf(D8yRIdw7L zsSAoJxuIF2IpPB-H-P!m(I-YU9K4&^4!~g(usOA^sY|h_2UlW8{Ig3JXSf6 z`8sNlqJo98+b?-rf{8g~Hb3AV=iU`4D1d@U_ahp?R09I%f+O?W*>epO(amQH8k?=_C7s3ZI6zYfTM!yGBCT`B(cDFG4rxT&=h2s78nz#D=8mIvDneWk8ls}NXde}Ers7J zt+Ti&){pQA2{5I!b`^7q+P(yx+) z*Pimo4CEB=4NdNN`ntY+an%1OL*ZU~{y&xEV8NTfie&oP@q;56C3~Nn5yDJ-6X(~a&(1?{a(R5^ewRD}(K5NyZ*z3K5 zf?^r1C!39_vlkoNr(0z)j7|05$xGAZUC{&NI(ed}+WYFeq94R;k1yE|pKDihALyrQ z-se_J=mVrMoJp884}*w;i6U#5L5B;D8WY9gLMaIoFa)af0&`?ink=SCuR{XST2hy{ zt+-drV!CXF+EWa%&#qf?F0IRxq!HE{>E`M<51#OL_((gY@fSZ#8 zc^)XK$0-K{GElR?`V2+XSu(wQ>NelH{fd57p54Y(|WXKc6latdGfnT$973Nqxx9+e!O5nwun-yDxm{H9seDz1eJ#-hQD8k zb(rIcJP!A-%M0hAM9mn5qakn$bPZ<#=>SBJDt-PbOew#wuWoe>P!^Aj6mPWxiAA#v zt*04+Ut7#RaC^S2pS7EKv=RHZ(b{jlYDo51bgA*+c=~>WG~wx6flyZ{i%>0AJg_Ts zZZ1jX3UoXhFw80A^r7w91lbtqqxn#ZFnby;;XstJKE+!`RS4nCtNZHSf01UoK3Ww| z%aQ}@=C>8A4Axn73+dB1pt|P10axaVoPX- zmoVO@r{TpvEq{AK;!9eE!0N*s>F}3D(j|j--&~i;4L2W(8m9hP+p9X5>|Z_ugg7o| zD<5MoPCp*8|124r`0-vX~ZSVvGJLI4`M z9b4Guf9(IVm_9^Ri7k~dMP$mxu)tV$L_;!keG1xq9_@HU9bxh)^niEyM$BM!L5MxW zIKn-f!qtD_rh48sU#KfaLN6Qu=!Gtf(hm`>p><49dfBA9YddBBb=Q0o=nBHy3uqC7 zWjKimJrziWK~kYBe27-5NZRTkT{@@ds#UQ;>G0Oz=GG9mJ7e+E%1RaBqWe8}5fo-? z_Ud2vpN#Y4V((aFNU5T$ngfWq+iNJSVuu)C5{BqsFfEdKU189?+P7*LuAP7C44(mL2=aMsMZV`W2x zW^>{I_)65J6egR^;)I#!vVnsUPHcmQJG?4#Nog3L=&YmITbIR9dPs+ki#`&9*dkUK zOo>xQutMYH^9b*t`9G|!!wLDql?|AIZ&Q!n-+#T@@upU~l0+_b(dW2T(%Z6X^4|WH zTT^|VN8Q~gAKsD125A52Y$?8c@uz>W+1o>b0~CqkpW`JfsfNlzYr*q;(7lX8)SkEa zwtPG|uB#NSg~o=P@?zmw_*U_%zx%h~_k=ivULjidXMjcGhi`Yyi&e6o(Y&Z+7t~L~DKCArU`|6Twn^E=Gc6F_*@I8P^jppSi z(|Ks#m`&C4!xGX#iem!dJK6gUC*qx@x=_{AqN<$j(GJsvUV=UVKLQm*BnLk>m=e}4 zk4jp|(bux{jgQ0+h5h94&dro=F(eD8<9>0U*MX{E;!@r4>q_O2&zYKCcs?%?VMCTBQaecWT0}F-m zeN#mUAOsLS!`melznu~(1LTHgwyh(aql)O_3U4S~3hz~?o@ViSgfj7{? zyj|J{;`vfnX_Q93_K;VO`-_cw#TbVfVzn6_haM3@Sv=K>d`b*%#% zw~V^$>c_N#TTET~sjzNs?4v7NS3*HuuOT5E!fh5rpSGr6-KI`Nou^LlvtX?s;)%h* z0wKiQTuH(g2E%7dV{BhkJ|28#b(kPhmOv3C!Zu zAO!c|_=SA*cM_q4IuYpwN3jLwiq;tMB+CNG=jG5z$;32!2?%>IM=CNeh_3+W&Zb4r z&u&Ll!V?;5P;~l}-@M5^OUo|tOgBx&)_kSLV72K6uU_gIy)7Oc9T$sbY`uHW_q^X$ z2e63`oXa2noOv%`z=`;zYmYBdUm=P++Mtvp2@(J12D`IH3QqyW!h_5 zka3th6kT}ZnTnn%TBk6?P7yk!?5|K#GsO|EvTId6u=d$p`+Tziw;;2NEvg?1;sRk$3y&qZMvflWKAQOM6S>#63OAg(9m=tV!Uy>KU5so4M z;LXq(of#zj};e2JPG)W6757u$iHrXKhE`9;af%(V$Gc2&gg*TCh za_fjR=K&JSI2bW+$QuqkC}TqwYD7(YeLfStLdRzf-ViUu)g0UDJ-sT4s{3%c&dky@ z_%wp8@ctntH(F0mB0z)CfkQEw5_7!5(QOcuv?O5-k`(5GxqDsqOqfZgLpyo!W=OaU zLd#ZD*BoP6Gl;evm=adZ4i+|l9*4TB>*_CYgQ@W$B~j|%L7y5s`zzhdMw=wgLucEq z&55dq86Q3{oSVDst^#Vd&cv@RtU6-czPrD7Y|TVArw+ueP|wWigs|!uJPY#;I!j^) zgg$ut!>7dH2nx!D&;$r({Bu_`zd^kz^6x@~OQmy#P?dasVIPuTd7++8KqmA+6#hgb^Dx0RZI1*3mNnex) zE7>a9?Nl6;ku1tsmf*NME0ySkxjOxTIASv5L2d~q{AR!d5{qtGunfw55PdBXgvucT zb$ns{Qilzq)HMQ>KMb<{9{wgbaPRHweTT$M2hun9#m%SaWuZbp8JOz_bLGHx zQnDyR-eYyCl~h4!sjd{fzcL7gTv13a745YsNK^VL%RQiw=le6Kn%t1G`0aG}VA;;i z^Rwa|-?RNFvf1zlp9}IuCvE3@`EUOFeI5QtY{n0@8Z=|ovH&NskWP4pcP0^Mr`5#) z)ti8uQqx3o%)dF>U^_b3jH_b`Stzv>l*j(Xhu7Owk&E>WtRyOE@$oQ|SPXh`$?K)B z3($P+u5CSebvV>6V^$s;GuEqKbwGadTE(ooB|Sn_)Ff@hw837bbmXTf$S#W_;zJ!S zFH{r_k!WXqm>`d|1mR!;H@i#WrVFna1X!u^KuM9&Pc;t64Zk4WrTmu=!jE&y69 z#-w$iOmhrA1b2yDF}2Vv2(P!$&Bh5?F@9d=?Vm96M?0s+6S$vCIdR-Hbf_34_4|~* zv&GY8$4|+iX*^`46( zTecO!y9lbwYCEFIAOws(Q`fu(A;2JSGvK2|N2?#~5p0H#&^y9Y?!>I3;iV#$l3={b z%O34`ZkA1p2m6zxp-<~o|1Gc880|H7UIf)le4SRupV&Msj(P-?F%<>mr(=hAXLYaK znafR1ViK-oij2dqqlvdvQH6l+nC^-OD42(dNB2k!AkL*iJmf+xQI1lI1Zq|KZrrko z4T(htS_Ed5aNz`qkZhDz4+8lx@|kL|K1&VG63zcdLD0h=KQ~OYK^I?V86z=Ur=|`%BI$rk# z=Nl2ZXf1vJg>a7$aXiZX5$Wn#4gFaV0i^LLF$qUJ07Rx5_iGT}z{StMqe0ELVyple zsG_3pMQ7CY*>mUZ&b>q%P^eTvp(@0g znFhh9=smRtCsCk=h)4`2!N0SMA6EJ$3x|uqBQ3L8_2wvODi(ExEwTFIP6ZJ8r)7Xv z9oh61+C_?ZUqA)jiqt)Vut>B$g`o~<8`?+dVb0%s(382SoiRQm`;o+gIS5rlgE$uCr=`~Kk3{GBAa^Y#9y;E zRZ0o;4>kq-mDq^{Trf%~A~!fz$X82sPz=^e3Z75-s?~py76xnNf&ns+ z`{?HBv%5R@cV#W7SLfd4{^ilY`RU>2%&*wQBoqdp;>9vqBs>s-M(-%%{T&>`Gniqu zDBndI-#>to06x4w`AR)lW=nP{bc54U5)Be&9DA8KNQ3k=Gv7g`NxCpB(nHRr@k-Kdsm%@?S*A1o-OFaww|nYs_UGzp2aGb z8U7KpE&srCu|2nb>~rq59Wq{A#m4@;3Zs{+kE{fPAzK>CKyE&&;sFRuXUdca{AZP> z`E3v8OI{{sYK-_j)XdWvVN3lc!EcjrQxH)(Ch|r4`^Yqm{~}0EVFXysNZkrr+U_76 zj+$VeVn-F^)iYDISrsZ}CKB4LFTLpL;?iPLs#BhFeT}@bvQoTrwley)1qWS#T z=h^Ma@FJ!r{$#CpxkcIAAGAJqUUj)aHx683COaH}P4N)9;?D^|m{OAFUx_f}QNFv{H$ z#=YvFFUdte^0NL`b$658rPm*?&u)2em%TVFswMaAHJ^HH`net^hIwQt9{&cY(|_al z6pr?HMs->;U0qyUUTp7fFGY1;|N7x_<5J;lb8XVDe&W$Im(l6slJm<=@^O=$pR`EN zsbT#66Um4D_O*JVg+>Nm9xunjVGkj}2k2Ln0rJ}#te5R%fhx3s#jTy21crRW$sW*v;bP6KL zii7=zZ%T)hi$m;eLcr`*6_-w3Y`D054=xfJOpv0Z{)^v0yD$@puc}rI?Sr2E_wex|ZQrgtCY5C)*=n*mt_|8&S=I6h32ki^_|3JM6vvXFaY42vA? zSwkNJ?#^3R_eLC89+yh5)o@o&G#<{)3+e#+3o_sU@;TZcl{dTFa{7B@;bK~v;^)A^ z#UgD~_x9hBbDhoEm**>si(9Raxm%h%4}6+Sza%yYWGP~!ZS(lqQL|ls~gT463$9bBTo~QRi_7B17|xz@)fyJ-G1Nxuto0IyRxz#i~oSItj4q7*7$)&1uVcul{*X*0>9lOTaF&~=>5hW$#v;$j>X%pb&)n4C*30a*aDTRV zv@j7wsi~l#s*{Ki&=&ffX&xB?1;Be2-&5$IDWy`yQ+NHL%*?q7rHT$*d}k?$s#_Z& zR|k+@T8}U&n1M6GC<`XQk804fC>DJCLF#R?U814m{Z84|TK!?EM_%r#ri@XO)9N0Z zcRlw3&{gpm*mJwHikAZ!n|}Z5rlt>XW=Nl>)_Kex zJ!%22WZAoSWC2#!Ow5S!-lePW){{43ml=0uM`9MgRNg+{`ma1)emNd2L}b!4C_Xu# z%^&|_lAN9u!K@LO<|E!{TPuepWCuc3t=-*JzHF`KgeGBx1@yPS^tczuaw6j5m7d3O zC7}5E;zRu2Dcu!GrWNEpg5%9$X%SRUjorcUK3)#K+e*lgN~U}{iL6ie2bd&t?Ow0x zMOnDi-@Ux(?v5HyE&uw}%;&$C7hZ1Oc@_$$%>t(Co3gg`Ws44<^IUbKK_4R^VV}PH zo6>^m`h+B{*)#+QZFjBv)!WsSGp!e}HkL}RA8n{R`oI_!n3`dlJYBn5B@?TV?;!eYb8+Q)A<+?W4K%;+({C z?t2$@TXRP{lauW$67r@mqO&KT;jEtzLdZo8kF$qQj>l$3Rwmoq7iDJ8PL~E!Q+Y(K zntMubj6W_lT~Fe49FJPElZ$m6bDK0|3rg0L42pQ3%SQX17mA6bM>$;Klyx?r_iuyo zanN++)+I_ZM|scBX$v1?j>OtVY`W}ufCVu?-PaDWm`0ztJ`g3StLA(bEHqTBSM@`qK#vG(%t`9Y{9OSx^ zPFuVy&r26g#c$5x3{~ziMo0&DqruO`Wx-z{ztSg7fNI|KdS2@FS1`fLDvllv4g+LbTqHD!e<-Ce~rG)8o@t@-Ld zQY6eNX-b0kDCv&AK5(Cp=y4Y+ONe;e0@a-xAs&Z?Y9xg(nDa4(=KDK~ zFKeviY!y}|nN+4=4(`^BaV`27#_9mP&!n8U*X}+LPBkj1)AHtPZH>pj$s&D8*6E%X zNxTpPI>C|f%I0Q+)6(~y&7GsuK~>YEAImRKrhoDH*4@2lHZwJB(5vvHeCab_aD9Iw?wZHj-2KIFZora=bR7v-p!wAs^Q=Mb{tHR<3cFW(r; z&E-*%TPbdsRH_}_;@o(z zc<*Gj`*7CB`(pKAqr3Idlj);>?qAnaH%cG=sTt-}M$%EMeEUXWA!V%#NA}qd8bgoW~R{a#^V|b z1rf_;1^Pw13eSp1PntZB|8+-Im0zCyovi8{9o?9|3F1?|$yC#8efx_53YkX%1}V9! z`=ES#v<7YI7c2_T7$Ec-pveF@>BYOTm$YvwgPBS z({^@I&K4;H-C#%C6%}d_?4;G6uNv*wT1ts+p5DpW$~cb&{@duEud%JZHGcoBw|O1514Q!>!tO;bhCZCtD&Nny0WSjt{3~)^S zTgkZeIXUY8H@x}jo;!y@2&yLq7$QRJj$`V}rOVujI06M6W4h6ULByAt@W2d>h5tZQ z{r>*2P>L?DDDQj-Jr3JwBIZ~=+v??VFV7JJr zIEE}MVq4`F_&g#c3GI5PVa5WVlG)eo{_{Qacfvc&Xbl`ruT0m@6&0o(5fq#7dM@X8 z3{#wcw7);VC2gifB*@?Fp?{Mt^oB%?5tl?oRZYmMnnc`!2h!w67g;6goo6~OIXXXX zYi^3A9uPfmV2o;&uKasW=_U9HBAL~-j&_JGPnk=v&v##4=x^e5U08NR=zSTz@ zlhIaJ43r-Sm)g|q)reQE7QN;xeO+&@HA_-&9d;WaKQ&!ib$4^CKRY>}AHiRys+*c7 zeNRPEqbQyC-K_Gs_rThfPJ=6 zf<;IAm0%=aMGN? z%>+Anzv+cIhsWKodM{mKl*1X2tD)Y>%exJ^_M9J0Xaj-M<~~qSx5^U)7!>gpynA|} zn{gy627!J-m1wMR36?huU!p-Eu8Z?3Mx@B13~0%2`zr5C$+OmMYh&a#6H~X-PxoX2 znK-9{_r>28BXvLDO7Bmtem=z7Kldf-s%u2^WZ!Y$7k>SH^4;X`C;zbt+C4XoM4mvZ zU*Mp02CFp;Cqd_l(?QLfe}AtJjpXd*@Q6NXX?l5DR_d5CY3Ly3^qD3or+VgLx8=q*l(>;4abe*YXiW9cgXr?WWIN=R6D0Ply=R9!Q{5e^DC3mCnsC zrH9HEej#hMZ^vo`3n9yvEV-3deRwoaP8(nZWQcB!&BlJ7|G9YnD8DEl?TwAm(P@}0 z`S-Z>0R--hl@1+wh*KikJATpjp!hZ6pBqPC6A&svgTE`DJj)!wo7>fW8;`HdQWFR^ zk?ttV`#2wpWN%?pZ1O$doNj#Ucf9s%FZH^Z8U6Uy+OCav^ShT7qdmrtQy+QM|84&J z!qoC1E6#M3O5hD83k&H6QUo3tSD`V8qkB%7UKv7-3rxqsk=SJ=sIPU4R=;3jk8Q&1 zBpij^E7F#ni}t%yh5P`}67V zNg(Z1-AuuIe|>U(CFl6V>2ZnUSF(ozCHc0MYmx{R-9u~XE{gozTuWXS&0sY8zuwy+ zn)k2sy#Fv*TiZ~2JUoBVzL@ACX4dj*XJPsLxUMQu#WS5u9L#>ruHHj30VDX@Bqu^c zC*p2NN+9Jdu1T_5sbJ9PFb4tU<#FoPxw%-?Nu=HvVECOCT+i0MA{mc@bKvElT#sf7 zw*PE++pq_-mT+Ta^68`5lHTsHrGr(UKg;er|A2yTR8T!u`%s7B(Cx>DJ7wur(W@kr zg`TcLmt~56koAA+kRS@Gz%Fc1OjzFTX)Yc4cH0C@RyPZ`0us-yc65*v5q0`%)^hT% zeD+(^q$fLv96y^Aj}^4kPoDTrI-=+=@&6D+5%!dT^{#=xqm1V(nTqj%aY- zax{#(-dHQfGkw?Z;_tDMgG-fn`}10!xc%p`sVPo=kVXQlp-Iib(hzyA7VvED?9R5x`5mt=uQr%H>e@IMbC%n) z3v)?{YMFNLEV6qiv2T}*cy3Rkd6;koqz+rbLf^`F#9@MP*qZMYw;~W~SU3s1oCvvv z=V#R1PW&xXNO|oZ0n(?1jrbO;oV{OTnm;OSo${F^qm|q7Bl?Y=Btf{W;n$B;=C+gs&p_;BPVP*e{@YXFYKYcpKE;mF(|ML++=go$nhSd&K@zZ1Sq|^ln){iFZxbjJMiqv5pXy zWc^{7ck_yVfocrpeGy&WHV@sW@E*$C(m`c?+2cE;?ixQ3WXk)H)wuh%%qeiM()nj7o9QjNBZu9rK`C@7q)lD76= z93F|+*tpF^-9aV_U~Bk~8CEDzeMt@x^4HYN_vZ9{%R%h0{mLLxU7d|&8NgRq%9YIc z9c?chbjyg%_?}L8GnS{Mrb>L4ZYg$9u$8i%uq4+${VIM##dCcf752#ry*_hW?=6z5 zLjy1oK?Fg>=)O42TlPM19589p8T*NM5*v5M0B$w+#oJ@e1E?UMz>qe;1qc{bM65Ipr5Vo+n3tM;51p z&P&gyC$+Pzo<;L97?dned{MuGa>r3x{7MFkR{*XN{d|%eHrdah~Tcf`lJLa~=UM1?pLM6faJ)JcV z!uGKuECmRi)uYIJed|^i&Y$nNT$31(q|`Tr?6+I7Cb}Sl(JBl@*ti60RPlJXgpIPs z<0uP58@{ULimYF2wK=1;*9XW;zl!&M)rvXIDE{)>wcc9a8Q$5s$Qhj+c8n;?W7bh- ziKF04bhooyj7x_|NG#76o@r}LRZ&(kxsNuan4mfmbZZU{7TjHS=FbnsL|aZb&s+T( zea^>tMC)57O-jfni;q99Tc%ZPHl@A%t1t*=7Y>QI5}BL-W&_J=swJYU6oN-}hO0dj z57c9b2L=T`KxQfjP*@{*d99I5j8Q?}gbT`cig;x$5@kYRUg8E##P=_sBT4MiiERmy z*-6^M4*EGxBc*?@jfmxxtIUN^2fsAYisZ-btap?ssSNiLImKKhKq7h1#jp=&EN=)X6UybsQ zjXY{St{IK5lM{dcfDy?bKw@%8(=MGh5jo|e;BJkypzzP|}24B-9~ zSQ`v4$bt*^NxI{Bud>1ZGsQ#*h7Jk|C8yp>pV}IFE;(o2Q~(-52Tjc)DBE% z4UJoIg<3LB7h&W}8*BbHtv8q5etJ!L;z#g{+actKOeGqcuELxF{&A#Dw6w&+GHW}7 z)a_0`we+?PQ}w(K~sY* z4`}F2X>w99k#tq@{uN9mD60F!U@oP!Py>)S9pwa##Z!sT{wRyY*SR;U<>h83Cx1=L zDatC!d+x83SE5q=&Mofxna;KtnU;^s(2oxdNvK%4&AJA#K(&;zET4X(iG*-!OVOd} zYts6(fcY^O_Rp`e(&xfJLE?$x8o9h1ILEv%X-qwz{IQk%w39+(+;6I|53mTa2NIr- zt~$goeljr=y|%XJQCnL)z!U2^EVB zZLxly)2CZOJ)tecB>-=Tqe=*j6X#_~LTd{U)}!^L30EEwwFbFpp-<7^2oN6}^6X3$ zXcMm++gLuOu<4Aqs$#j1)kD|`@%H0Q`X}B^6k5}#O2?EWuYG|%jlMJXu=u~O?(v{5U?ffBfVUE$Tm77>2G{7U zEtK7}MW3T0`6P@TRoO$UA=j132?~T{-7-gnL=kSqeyD8Rb)M|%bG&iL^5U( z+`_V#Cy;f0um*(L%{Bo=;wss`wRLkiY+8b`=kERn_dxx1@|Cf*QlDf!laYz!Uzpk# zMO8nuIaW9xM}4vE`FAve8o9ULx?k8 zDd&wdUH{y-XM$x+r51O{H&tuhAJ@~r7-w4ZJ**i_nf@pHi>u*f>wlj-Uih4*s-N20 z3VzMtde6PZ!%5;dri=k>r<;a2|n{0YXEthK_qr1DnaZqL$ zT}qm)h$3@87aL@=4@+UO3HGoyDLIBmi3ziv-RcUR)R3q+qE5%Bz4m%4K*{v*H^n?n zNA0r^Dio)&Zs0F{6ZhY&^@b*r1zSrPHhv*|Y7A*Uw`;;x$@KGIg}2XJ5C4^Hl=K=u z5-V5qsq`9S4eEvi0B7>Yx219**C=C3%f`C+D~A8<4n#MuZMJ zj1cb(fycV%zwLM^l;?gc+iA$EhcKYsXyNQ^XuiEMh)1!>)8(|GRLn@G)41^tPDZxV%0}kd{Q>q#6L#uI zglrrp;nOh&$vddV>;V#|L~~T$%tG+=Ymt1FmdB0HF145cBzy_=N0zklDndEnR6>ET z>EGol2_W$j5#k;KO2b*&uPmq~Wz( zpNfH+i;kei10sa3QuR(8q%X-|phR4QF9W^&Awm8cb50Vkcz1Aoe7$YFKo`1w;X~UQ z7hQX~<^`Yi1;gHd?ObdczN$G?^mH`o@(;7Y5Fw2l8zb6(;#7rIUq#hxwsy(HgaD;A zn~iDNUc-N%{`&{i4u4`V_Wyh|Q`nnqA0GZkve%{ys>luh2L1*PK*dqie!hvWpASUd zvI( z(mFBz8?OBWxC=P$H9huvw)QA?kyP@&A-fclNAnL!cSBz}g~{~}l9JZ^8HhGJB9_xf z`?L5V&eis}pk!;@f_7*Stx&p)x*?Sk?3$!fc9P0%0VpoZ&RCFyewe0add(y;8CRr!wWwlc7(H+^sYAA?PAFECyaP?etT z80p0FWL%ZfGzzd_EfM+geO%El0h<+m_6E~VSnitRCF9ylcgIQWXbX>?s4-*DSSY3c>d>U@dRaU4G499gufoB11Zqq-zP4s8p_lk`t%LdECuG1 zKv0BUunAoVb*IfTateD(z2+uMMR!*ZVv2?aO^CZIZ@20DGKyIHqF_P- zoeS=-yc3I6Wf<(N?$spZ{Kpxl+HcT*jVWmu#TRNm7EPSgy-_(GtZBn^NUW4pg))oh z*IlffT{i^Bt9fIuv<#fKl|dT31SBvw6b ztk&a~e2_be?USVDRRwzl52_)3Epf81mAds=1T5h;s9P0RD`DD&{*%wLkvL_f6)cWb z2d!rxKw(>C@aXT!G09t6KFx`1-63QBajP#d!fAVSoiy2@eHO*+w@of47q5r zrU4hCla;tuhG#ZZ3Jp4bApK4|50=v{#1W|9Oqj1UgEl4 z`^vr7#kKdUnVq-Q5sQVs#(eY^q|__LU{4@=Q6Hr{zM=@*T=ce?D z0M}SI(K;#N{qz%bJHHER1}A7Ddvb^10KB?(mvEb+Hp_x~B63HcY7(RzNa2DfY%7kd z23o`f-AGV}oO2QRmv!hbgR;A>UCFHqE>+U=8!WfmQuz+z<2x#DAAX=*cvNO7Dt<)h zg3nQ0L&-EJYgzWE11|#}Srvs$FVQPGOlaEnJZd%dhCGBc8bLdRrPU5Lty}=%>&2b& z#^s4QGi1mS)6C$tcszPU8&;(DU-{4m+Rpg2?);I%QET>XK8Kr6{;mw@hSW!#pBi?& zwq3j<&Yq-@Z1>9Q`E*@S-m6WyIPf)pjc0nd8Ys#jKnC|L%t@18*v^#`hehlMx$_$k z60;28>=A{dmkh3gPCFnJBM$(jk!)GcKLqR128vOS9X0fC|jBRuR_b>g?l3*l%USe@EnsEqehl!M8mSWNU5u(W{rTS%D z&%vV9B2D0nbgiD9)s3lMZ+Bd-C_?1BZH~M4qu4Ky`Zy*bp2TEzJkYZ-O6qC@QgFDR z8fZW@fX#GumezGr5EGQSsz#7HivBK}7&DHhEhHc7;9orrH~Fng(9IdAbIrLTK!J+d zV5wTDpP_J!ZdAHOo`i`92`AR452_4<%q32rV1nOS*75(ZrQ?U!ROYVV z%H7=!nSb16W-;7fqTFYGRRn1O8nq+aUp@zUOok4=*4EUs-8Tu;L90``qQbozTVj2^R}T2%UPX1~!MG{7;xm6tTXZ zb1pEyt*$Opw59lawcqS;(_5DHoW9UmB7e!>Cfm(MdCnhdnuwz70wg3(%DNdreIuH- zKhA)P*+~os>^6wLFx&|E7`dZNIGCZe`EGlJYw>AG9v=!ndER+<1KPv`O{y zh+;NtWoACz{*dLa03{JSY}ONp3>a~`YAdNCt^L{v^5AXLp^WTc2qxVXfu04y(6qo& zO~I6t=doT`uyg=2c`|YFdDGi?sz4d$XI?xdyY|xp=m~@_+r+!2jg6(Ho|ToogNcpJ ze43|^vbnw}wrO~C{%YqAk`G;cvoq%ds)qch#+iQ4TF^6+X#~Nl^eO`abp&5!Krn=e z^^zeug*hp(Bf^QQ_<+j(ytiOZ8Wbv{1qD_T#a#vIUcHW;^~XnbM@QC+NEo&VYiE_$ zua@Wi=iKH*HsQQMmvv&mm0CApdxiUInvK;rrZm?+5R#awlp%&Jn?%H9;$|Q>(OC?A z3Os98GiyP)e+k?s3v6~S&B*v4p5B%^O5cCx3W(Zr2`g3?zi7AADZ}@ry0U3)^eE4a z-GkANu_I`?5LbW#(hQ85wdJ~jv@8k2}o2Vu*9ptNE$dQ)Qhv3&=Hh50|JH0Yrobl^%$dl0Bo<4@O z!o{$Et9$!TZ>yg4O@9+wx>qrISG^<(`_ZD3h@&-80$0H@(G0rS>TGk;Gt$(kh^~NP zV~QISE|MxX3y{bRp^he2gNY)wv_R?-EVhhFH|q1;%@Q$X8Cz;y>0S11PhR=quaFSY zx#kR?LWRe#l{&)z{v2M9INi4@y!5&C`1n_c-`$A)gM*7PFW*BA9&Z#+&C1|Xi=QDJ8BVo~BjnMr9XVT5I_I8vLkeD-0J2mF{r9qgPlufg(o)wzBkCOlH-)KYM zGgwMKZz0bnVa5bl2Mi7eKV0gXt)Gv5~ti2_`P)u+SCH z=_=4a%hIgZGbA<2|gFh>+hNkdS46;Sl$B_b%uS!uUIXg8II}vT)Yo?i8hs}S2o44mz9xH_TIsA8~ zJ=v(@_ta{>>HR*({5y)7@XstCpUUHagRgtD(=n|oS2P!(3GMVEB3`@+4=dpGHdRp2 z5UVmGeIT6~?&+SDaKnU-Ne%>oKy1{Y<|L{p3>N5#fpLOxDEZh&vo!SlHVW#xnzUJ3 z&O{U)xEkj>|M{iFc&o?Lr&dp`jtaUSo~&P(FEX)L6S|V@6 z5Z!+{(Z)TABKX2UTzeM2l!^q|#R1T<#A;2aGEP^N80B$ri5LiySw|fX!egT#Rn!38 z$ZpE=OTDA+9Y}`(JtZLT#U|)BFBwT(^KG+Y**RNEY8qEPIvHNR419gLQ?qy2aqesO zZS2Wmrot5;M~%Fj__O{_HVPZIghGyWp8WYfDFPT)p|D6cogiG z@mJ(6bZT$dsu3ujh0@PXu}w!MP?Gf8D_@i{trO{gcC!N2pol~~8u$?+g`!iFOTR1A zIPq3|3`hDwC5*$g*jQ9OqHGKPh4S-Op5ztF`%?@)M%pbZOc-c*SA*BBjq~P~ zx*+vOV)?Pz%3=e?h3^$j+Crr>O&z;wG1jQD-kx44P!2=8Qu^scJmJ_Fq?Tw=T~Xd& zxAm3$pO@`NERsvk!`t9R{7M@ql7Cb5 zo9wq~NhKr^GwK-F(q?F<)2Sk9mqZoBIOl*kSIMPxL3ZaKsuF$MvtZSnm zRt%fK&>6-49~IyNP&{Ys!&r6XR4g{yi|3lb(e3fmjEW)*+Ao5R}+ z_m0bANxvNVsg$^NmG=vOK5K{@80IOouus=Y4?@i}=}R+f)i8hd@{k=piX9iH}R|*h4RY zuS%ghal$n38C?P8m;KlW(QVifWG0Oq9e!Z0n@Msr8-H8pNYI+P}ljifsAQNdUdPR%~ zrD!6y46js8&2HJtDNLqc3GK+=R(X5v+^2BuZGIcaGo!}=51#C6aC{c!OgGlTTt%YcfH}0200q#Aw#m1Eg6g7aanJ9x?C*!& zY@bni^838+Ovs93IpXB!%lV9ZMn_9q>v=rYgSVu;DxPD!R>T??RWNyOHZO{knMgR{ zD>+XE)S+so@GMIpCLX#fq^Gn%Fn&0`q7r+l&sqbFbs$UGQAV7E_ADkRfDO!!U>7s- zp(jfHtGY15u8su;q}Wzv$gndRd=jRS|2T=~eq5talB|Wuw4Q{=kVa?o09Og#9xe~8 zv>t{~U<&x$QA37$gp-LN*rPbqEB9ST&!U%$Hi-P6QDIibS- z{rPcTktWHfGIJ+ii%Dj{MM_5Idz`)Hf*q6$Agd#!Dw}>6Cb=%@4*@A=L~1SNR)Jjq zNFs!pR=LqeKrI|c#9OFG4uR1)&T3rraXKwiGB78Stw>4F6r?w7QCgi{{lwJWRMz9% zHR#~GYln(z#PQ#glNg=lh`lenm!~HeyUU+9`3_$`;cVJ=n_RY)ll~7=CQwIGZ_Frf z2F7VLqI(-@e^#1fq3Be&9y~TgPwC%Pa2xzWWwlUBwG9Wi)^W5Xl#r7%iBMCmPdw%I zfm$GbZYNkzd)2EW!@Sl>xq~GiKNT|w^jREAvdT@DKG%lbCysMRBd_ehn-DWlr1i+W(@auMl(3vxrz+qSa zn_Me4X?#7c#ZyV|GUwe9uq?OrcJ|i8KR+{;7sK{eGgSW_h21W=bL-8^ZE_VqVNNnk zQmA{%cDI&PZNgs~60eD8$Bdd(AmBMHxK-XLBBVxd2n>SQvQ?Ro%z9~oAYE5Cfl3PW ztPYO!wJ?q?)JI{_xEVAUicnJmGeoH~n;3j6YJ|4-jqtNIh$&7$53*NUeK_VB@;oRl zGB?BjexH{tcpPwfQ8TU@aWLTE@YM8^^;X+hPI`mgT3*9wo-N7kKO0}NDArUry;)%+ zAIe-)dz`Kz9G)3Bny%Rg2f=`3TsJd7O$u_y84uPs>Gx^u2-}?u&Mgl{SKXG1cdN9G zf;Vc?n3bUzh1&voe1B9?F|zHVF}1WX8CGP}?}?3Y*WP@}REFWow$-8rO=0<)^@|}798b1X$vaV1sJjaS_t~@ag3mCUqRkl zTxiZOIhJ9m(&+`6qpcf3`YsYCS6KB86FA#B8Fd6KO|FzizE`U%2t=+%{yH10>eExp zj5#*(2dyR~WVNqQ>W-w8u(0AtDU~Z%jK3W+xpC0^%GXExrGm$qURD0B(BEI1#;=7R&c@unr4n)cb4jT1VbJSB z!AbLpv7Chu;k|Xzrm;H7r#YGR3BM4`{o;~v&Zy$6!t5&gy1`gEEJUh_CV`$4ZaasE zFhp^wN842Cfj&Bmxe|zaA|jdIbP4`sxg`)C5XcHNiTa&N-lEpW0-bcbDIGRgjWGo# z?L#ZlPl7P}!N*CX+2@975{0)}B;P)|C^_Gr-)r+*y4a>z!H-u?<5hQ;-uUj137?tS zJNO)$ZD%jCm}QT=ac!%4JYAsu-<6K$bXPi{(J4mUR=%k0xtrO3`C5TiGG93e45p*7 z+jLTU2)brW^yOj;Ae}M*3#->qk4EYpOo>|p0G26(!A8Au(OgNGHahBPFr1djo+{za zzDHwO+R__KkGhC@-^*qt=j?j0HWmD*HKnQQLq$NzW&zJ`@YKymI&`j8v0}3Pt&J~J z+w9E-d>Yt23SZA|DdwFI2I-^>ij;Iyt~(}m6XexzlP4)eS{!P{lDX)kvz}O`rc&S* z=PIX~;X~@{5@ZamwzsCf*Gnh!V#c@yF<1}WCLe(;Be4p*IQcdtNGDzeBG@SmHg!k> zBvT6VbYueZ5pD_Ijini24Ka6&&C+bQ=v_$#CdB+MZcgZBb+i<5W-iIP3Qi`FtF^ta zxhyy41j>qgyO?NyFL+z$CHtoC^Urhbxx07n+zh46HBIlj&dw((5S)$Oh>(lp;e*B@ z9$hY1bCO7|!BuM7EV2m31c6}P$q7mBcEr|>-VhkQ;VeMlkLit4s<+YN1gl3zM%6>r zssJT8U_vf8EWv?eFSS@ngt=N zCz)Wv8U!nbG?;S!GLFPB15(?6NZkQM{{VN9smyAfD@i6GN?tvt`gt|eG?fUFWV?|5 zO@W}ESS`X;3R~!W5Ym=6-`dckaM$**FzU5J{p^gT})5c)pzc%(*eZ zfbSQ1BZP2gm(3lJ>JyG<*S9pRhL~OT=E6UU0YBwrYcxM}69u_crn8H+Fxia#fwz&T zYFY?RX7WN!Udq;?)eT?^z$5wqS4^^XY)n)c;Kl-UKo1kCUkgVC8N(A-d8v`kWmI%) zh{#7TnVcviwn$J7DGC*Y*!v(eXds@9OuIFq*vHeTyD7_T7T!2MocAep>2%}#cA@Io z_a8!CmwhoD$-**gUVckeFU=z4uqMYSXJ{(*PR^M604znIx~y?tvbPI&z3o%X#r z!T0TM0R%BxiuMC@6eiWO_UdUBUTLYKq~!fUrbBR;bPXpH!PuHkQbvRhV*;mO4~tCi zSu|9$>%8&U$+=Myoxj>`Y(^IL78eyXr98g`KsF)iihN1 zRRv`!ue>DVy1_cyqC&LjqS-54b#Pzd6~!0(dom0Iycz*QKvOL;*Y?1Y*f45Dn6Bm( zxpBm#@ zS3)kg)1IbX3kWsZ)b%|~nlq==Tk5PLxa1=%T?rO!C@3|(oUnQTEtHi(5D@c72*Hd( zGvk2_0+z84Jt8qyYS%sK#BAX4)V4@u0xUJTUu1!GSL>fagG>m)!GmYW#6ou!W2){& zr9nL$%&D%XMdLF+(8u^%;+p-x^M8Rsmy~9N^MkcBzojSVKQ?!}=C&OQF%|Z9_tjOW zXFQFAQaVMrX~>%G!dawD^G|xTPYHi#m7vmeKd9nFo`vWIYci!8Bk!^B1@a$pOZ!lZ)Zv!Wl}F5_f3DF^CX=k`VcMR}k*w63v>5sz z$0ZQu@YPcnW(I>}L#iuLta2T?hAWlSBqcqWLCBa)h-QBnH)~hrF;|e(aTOXek0o8# zLxC_HIs!4oXuZk?F)o+SrepVv&L|wJt);`&KNB0@7+5F=ZQmD%CwqJmr)!e)i$@OI zes}G6myISKoqh^>Vc^1Hcx~d(XLU+wG7*_oj2zxGrh8ib(^9xaH%b}P&B}>UGmk{j z^J9}g_Yxxj3bpC$yIBIa;maQX#FVEo9$lZK|eTk_-Z~Yc-cp#ZpuhK_`K|0<`7-Re%{h z4Q11cEbhMz%2aY!=o51nW>3%duF{6FDjUJXABvQC(~+2zO0?a*GM@_6y^nO()>k$S zFBjl96>XYGe?W|X4nZB0=Nfkjd}>?KrD!U83F?rfuK z4I)yGVB?1s?PetO7!C%m-rj zJtPal4?8>}j?X8@Z*^RLpZMe1Xm7E96VuplWbwKbi>1?RtY;cD5VO+;(s8gouheDL zW>XYKkde%zyg~Z0{ZUFlhShZuxR?cqJl`mmUP5TyNUR1!03>t0TqTNo)K}|YiQ2Ki zDuPn%fQ2Sl0+GTX$}~Zs;ZI<#!P1ejuNKUG+G`AN6&f`^4mkb&>(54M@Pp4g`IqPK zyB5Qb4h|F@w(k1*2ERN?wr@-_GAAXH2qWIj03jU5xR)OsE?`CeYuLgv)?kn1P_8iNB?Pg}b7jQ2eq$ zHC8?dD}xAzRY+XlB|$3@>*b22(TDS4?7*P)h?Ta}(Gp?6otC)+&BI(f)fh22BlT$FJ2{a1$N<8|PY1PgT{9SO`0ZiLY) zs7FTqzN-81c5J_i9tEj|GgfNMN92At&n^pAJUf44Ggk|iGMo(V$S>DrcZ%%QTdg1z zN?qo@p+VFA98w?xKlT8$uiQjv5fW@ywRiJrEpCcf2;cuS9{wQsQRsulS0TZd86L}z z_kJi+oTQ4EdlA775w9)}Hz~0&@7dc)iUt`!7o81kLdWdAKm61_L2EI!u(u=MFXX98+s54OndcKdWT><%Nd685`ahj|F zLYB4ASY@cdh>flGWCtLvJmY^^KZM#=!g4~P3eT*(H!op|i zmCaVow_mO+s=j&qq=S;*1^?`%0JR+K?ehzdmMm7W3j|bRDX2I8|7C;6IwaEXsA_;! zmQNkgrylYVs6!Xcs;yQ+eqVQCpn@uU~71nG}rt?9+Om>fqIqZ$bO-PmFHcDO<>bUas2Xu!Q(ayr{tpi0ruaDJ_7 zcnv+b!fUdHNL3C zQBIehrn*wk;)57Fs;nQTsO%}3@;D!xsGh_RD?>zQqnM{50S%~y?^`L9w# z^-r!18Bi8MQ)k^cjJbFplV}QcA6E&?Tm!DOWh3X3?_sD7%DbOHy-E47wS`fgQnF$cB z)YzU?Pf{`#qj?;Ns7Z_ZRU`0s=n^ilMZDiD(#w1xai-tI{J|+lvMw5(iDnw6_Ij>Cpnz(3a0i z;1vvhniC5gO4n2@i=j=ybFr0@Nh*dkGTwLB6uz?-E_WS&`*C@6JUiL89DerW@`$-nPrq~Kk9Z{op%BGn0$eRk5~uO%)&rF&k!)^=vhE7rk@=tYdNX@Vu>#93 z$F^t|-A(!1o%u%R_y4q3Ju81cJ~ET`XxuvV(7t6)1}SG;1*GRtXUENqCBWKsUCjm1 zziiS=orcoM=2h~8o}FX*v+NA)45)DObw24m7H3Wb1ZZwBT>g_BMOV`AIZE`zCdM(2 zP0Vagc>yYPlIqnmX{@6l%(m9k?Ggur1x!$cU;!>V&PGg5t3Y1aWDV`Eq;Dmkoo!>S z`7zqeb{fJE>u)9|49{7`31e3}eU zn<!Z9e}BXly)1*O05SfE zT|e~fm;wSfJyb$@8DkJ_VpT2hfJ{w>H7ljasFEUKTHAVHQKW`bd^v3E`0`aulYnmO zfBKV`bJgxU*MeNX<7vBtj4TrGFHW6x>9=JPX|dmL_HX%?zqZQLaVLF6i*M~PMlQ!E z5vJH^oOB@1RUU`?`%9&Mqxc%$>D*TB3_aKw%bR~+<8@=F{H&vu$8+=N)ShvE%qlMZ zgYMX3kS>QCY_}E|gJ*JPCHG)09t;7~pAoZsqxb`e!>GtqUDkA8P3J7FBAEwqeBl+l;{@6M}GZj0~A zTSYujfci}KFsC)f9|IX=pHWGc(n~J8kBvM=As!O(KA^3VdI*T~Z#R@FF#{XpEFUIs zB4n9=kb3Z)_x5&7X~t6%p9Rt8FM5oum z6WWpl08jwQ=mPwPH>QPZVSuGnSG~})xEbx$sGb~2Cp3#nC+eJ0nK5yScK%Ky0)b^wsjOiq}*-XK$jKS@S6tffcLpTvR$L?6%%8J zIwM`}a1iZ&yc(B@CVLi2My~&1J9pX_hV_cH7Zla~tm0|JX&=kp+Vr>sIDLKso;C8D=DE z7z?2TQFF~q3a7V?RmzCkU9A_H8Vc!Z+4n{y zWHhmni{ku@Vj6-;R2qLQh>)!^bQA9I|L?_TizjZT^wA9N$bE}?4}JB-jQYVB-ri8e zwISNX=j}s+Kkn!FU+)=sR>E0|Rwsk7U$JNwS1I4GzqI1S$Mcac*cg{cq`ke~)7oeS zqD6}gkCRhbRj==CX=QAas2h6~m{xr#GUh`sFA&-!6-81FDw0aV0f@Z{AMYiW7<*2* zWPMD0ffH`g(`(EP^mOZVdEWfWV}~0? zy?tj#M37Qv*yH`ffs-V^&lMFyX_Cwz#^1ZkXM1OAP84k4YhuG97(KXO(`AG3G3Fs{ zV>G&v>_a&bIA=-gp~z!{%6%-D$O~wu;YTKFF@r@L4F!K$8-1Wux`sY@Xr0D$36Jg&3jcV zwLeizAc_F_fKq!$Z3A(4x-Jo!*bL-iEvq5ZKa$!^C4E9@m5zY=0W4*;HG`j6yt#hz z?D!R`rQZ8)7X3Q1)kWjc0=j2GHhr;_=^QF_bJ+Ym<{5bipo zfC3unpHo2JOOmOKWD=}+RjEx1Iy7Hy-E1qASndov>*L#1ef;Lh{^VH4myUUsxx0ML z`AvK>E%!gL`p7ST4z`!ry>(CZ?aA?Lvg zRL0CK({z-|%L1EbSzC%s_-GX=eQEyt8A+1lP=Cc5OHF2_c6NH-DrQSvFwL@q{(h@?s(N>MvE1_AgU8k`@b_{)^Y_DUEPo!&>XgtBXUKg4 zpiB6vbT4W2U^;<$as08Mr^TMeQ=_?4v)!pUQXY5T$ksC<-RR-;x{wN?FqCWqbe1@~lIFCujilerI*}#TH{WH#=JPMkgx{_8^6xyLl1u* z{yE%PyVx7sp-5CQ6gJNbs~Ej1tlwDcac}Fr`Yj?5cM^qu(xZ?Qff8VsK|n|E&bdnx z{lC_Cr`yu>hRyckc)qpTR+Cri^*Cxtbq+jZW8J7{AlA%vo>l7#F4QPgOty+ty zW*n=aE06V2M^TQ}NOnrt3@I{_Hbx7YZS1jvMN>Pk;7m<3p}=~TBkj=Y_^O5)xvbCc zW?ep8h;Fi%y;SHMo?RIjpx{X-{kl4jFFKkk(yWB?`o6iO$S;;=s@ps;zpuDm4?}91 zu$t1lON@o(8yEE_ipPjCIC>%H#L#-8!wsxYN5l8#FSmPE~78MaoSv*=ZK7jOE{rjk;6tj zZVCM)_p~RG@a%e&x}|%2eBJ`VZst$&vytmW{?`O^19DcCwpZpePm!vIrxuw}mH!26 zBw8F)Ka4DH<2Ku#{QBy(Md*y$NTLkW6m4?A2*fg1OO4+3HSt7rgbb8oWE@3l5n@ji zO(@$3aL;3vW7Gox6}vFPs(dbHToSfXO{&sIAqHONZyK*GT5<>&p z$?8$PT%WH6x3+fpr*AC&OX1SR-^1qcG{1O~arR>G@BNU#a7#TVM^ciU-cbtp1)9C*zxU(C2Y5=_^Vz1GP3abLLYEq37i(!|E5JFPv3h!qPpiV-JPqKtx{G$*ZT`JfG z?O!BSW|EwKi;gb9d%;saV3H%mVnlJ>%DY>d1TypdF&`ZEU&@r<0nH zCLTigsAyKM$+2OwpGV`k--<5z!d)FLQfqs~N`h0a4Ze7wX=ounBo(-t*|9CV1JE#Q zHtKs8nPl%TFTh)Qzn*yC;&u;vNwMWZ%&X7}+(hW-s_75q?{r^$*=ToADY$-=dgE8h zFFE*B#(wCN;NQppCXzhTo*ey~$jF%7kIB%9&!eeYxM#uRXg2FEia{YFf7XF8V(EQXTQRT!Heslo~ckL%1mcu|3zmoF$3sWBWd6;-Ll%bn_pf{@&v7N z?u7LHn106>@$hJWQ}z7!WJO3}uwuyT`GV2?kypRwTiQ0;=f97AouBjN-wohteAg^q z#;g7P4gYSa&0{NO$%<{CdHcmhhj(N5Tk>D7we41PWPDNdyI7y}V?JwZQ0BH`a8ts7 zS?=jhgub@ZNTw;}zVH7soSiHEYg}=Kj5Q7hq<~JhXen1hVFq?)DZGX-TuzE?EdT(a zuheAU9a@Av(0e_!HCEO}8VPF5=3U!F%Sbw06Z z3yEKPp4``?w2;-ZZvUZe;E2btw6$!xX7Qz7afM-j`BaKCT6FP`uTmLQa1>(#|p-qYxeY@q|I~8(q9ydh%hTk+sWCqeB`M? zW|*QTSsRDtoML|T^KyuE31%$=b^pn$e&u7uOFQl{I_-Jr!HJNYIOHc0*vsK-NQHr6CPkADHIwdl>7j&yq?PU#a zADY6Z-j^#8zMgJUyHY+T?!wHu=^hjw7##3>>!jzKP+ro0l3&5Clbzv-;hu+(Z+e=q zg{WzB7)Vq|sW8&9N52DzAGF_1qMUWdO?b!j)?`C#C=NrEy*ihE_1KMk9vMH_U>n z48u|p-PW8kQnX

Kw|Cvf2cpPn3fq8h}y}PWH>Gd3df|DY?{Zh3r0R$Hvzo;h<#Z(!Y?!?yaOOqtft(}slF z5u!9pi9W(>)IUzFBB$k7W@52Ps7ShadXz}=ip4~AsJ%0hQKF8HSvS~~5eluhMpH*I z;Z_}lF5H}+bcl3mDUkSz@OW3rD5-?lHs`@aFq-Zb+ z2zKm19L;tfbZj4V9PvdwIsX;UclUB*{p_jauJ6l`khTHkk%5l%N9J}lSLUv~O1hPP z69aJyzTP`t{q02M^Cq_YOjqm(F+QADyoK z9nKi*QJec_jRrziB#x?I6o_PEqPnrAv)Xh}N_liF1Eq;D>bME*N`l}ZMC0zLlU~l1 zq54llxO5bn2}qY&@KCZeQzp>Za`WJqV{J!M={kqUm*tx$zbDgnpZr_ttFfBT+eB&c zT8WHJ!0RSWYcOS>5$Up7i|Jew{N|lC-c=Iv6MbGD&Nrf0IeAx%IfSpjopuV5`?3?@ zjN{1EauawuWcZ_~v8uM0#^(EjU1GY#hkC8J+Gxs<3LT}FvR)<+bQO;H5%{P8 zsu-hmVk1%u;6xkvwVN8u09Llf{BV@4BVI+hiQ)PS=n|i=s?|SbFSHSZqPqphmU4ph zDreAv!INTZtr}UCPI_Eqi0!@iuiLGx%5v>Lk@}dSjgy216sVg}qz3Fo>bTZRbsi;u zYW9B6BH+u_DpJ+R8$Z3~`1tha*6e;0$8tf$+4<}~N8bMA%5iAp&sOv$Dc!DRM9?Kr~PXN5<9U*{*Ld zj-4IxIdnZaswk9n=)Cy5HdYa`OVO@m7hlf#iuqWab-!rjeZzB;rPHFZl7p4G3V2|O z%o-GiJxj;iwRZe!MaCn)H1kd>EWQr>60W*nVAVXoczF2h&)UDdyl*-jIu$~BG|bF{ zrr4{^QOYGZk`kg*q%7%;=*XZ8BP5keHvkHd5(c47X7r_Y9GTE-vcsrJYWpHAv_0W| zrJ#zlYB;RS0LR$mUoLZl=Dzmlf>@4wf`cQSo7`LL$lvf1hCW=g8j z7mtdxu9Gzi)`m;WXY|9qN1 zd%NgUKHsqY-D`C5(o4~35(ihu_z$hs_^a1H zg%AaaYE`t~sA?T0kuw=tk>t#JlT|7h{j`Dq96RYXkETb(U3hjrxe}{H+$lAmke`9z z`OV=P-wn`2uzrpf=W__XnJGV$<%ao{Z}w~X4{pDDS@ZT5=k0NY3ZaVSPNlAgfBz1& zQ7YcAIoz4baIvI`-C61|t1_PACfs)y>IKek#Tu5+HbGbnhQ2a5T?3lp8;I%nvBGC6 zc56`@^ynxXV1EptH(Zc@Wvkq6d2D~tHze#!Ysc-~rMKrN?-W%pe(xRJR`gqzS*&yP zzqZD_9qqGs{&82dZ92qRbbQ*xTtk#K)!(^clexk_7O0Lq8oG0(Oxa`i^k&FzwfECF z*V;|tIIj<9^KTY?+N{3J=WUO@d%v-^wl#e6ce^P`NGD$BL5nt&-ZI^+G&4dtw&2sbVd#<=)EPFgH47oKrS(h(gL;v^BFChL~QPV+l}dR z>V|RU4KmZ$8LkMC>9oZfU9InXTlp{r)#k>rw^S|Y?@Rsq?f*Ei@p^~SAgTE;5I$Zc4>})SqD4w61 zz3Su+oJ&Bx+<#liR{l}0zNVnh{_bBY&=_jAD{01{5MO{%qY9sjfj6!s*mSRu2*!FzdEqD;w@#FK)ntVy(Yjo zzo=jWk9qGt;`BN6sfLHAW{5yD=O*VLghKIy@7j;+?mXgN)bV3z`}OK!ui;MnJZ0sq z{LIk;({&;ENwK7ebnIFaY#`j->4N%M*HiU1zXXT;5kI_-?!V}3WXe^ZG@dEL$OX5? zQS8FRe>5O~=}oB|hx&&Q1n!9%$!E`|+y_j~N$G196DqH)@Br$!<263n*BU-^foO>2 zezvo9yQ{?#ykZ}~AwCsVUwq&DiUAw5N8ol%T-;d&zM{!)|bsXohKJP0{6B>w>b+VZKTtOxKl7NH5 z4P%}W!t!qXkP*a!1kR`(suy$C!DEvURLE)&AR<07yd>dD@t5|}#mbS#zxAEJ^I3R> z`kT9F4^HH}GHV|n2|cdsFx?KY^}auAt~A2@&68ZweL{M$Qw$$8lo%Qa#u5HD%tL@h3-`&kwe^D0w z6zk)lPHBAag@st8yb|QYPS$H00gp<-C5Mwj)gCB)CVr(58RI}|o{ZOoK%o@}SB5=$ zz~*?75KEi}4Rhv1v%`qre_~H*o-->d2!Ba*#iW^gew3C9@c(_df3#GU?p(Xp`ToJ< z)la^e=O#}*cT(Lj5Uq$gT`A?!oR7%S7`Hkt$@J)NSWOtT@;_I-5T>^Hu0rPwgItxV zSI3pR8V`;Oi6AQP%K=bE8Q`L#KRZdLr7M_F^dHlyq<|&bOrG>S^Ur62Kz_b%coMg< z4W}2nNb+G1Dh~lV`0mVq6WUFKt+D9)e7+}+7fw+}@7sK;mi1&x4v$ltob-;z>{?{n zbko7wQ+hiICwh3Sf&7;(HH{6!sD_hlWe18Fpx5CJGv>M5m*u^s!~5K_i$8Nob)7)!sLiKsyK?qTeywYVRJJEm zBI+ZNK1Q7#V~H@#5T;r{Mb~w}Bo+bEV(itTOznF)5tNkg;wj@<^W<~$Iy1VvyZz38 zm*EQtpYCo?ls{enXKWmKea$Fz zq9I=K^hoI@6O;y``2jqyLSMaY{38(l$Jku>4FxE^XT)Hm5&4JPl8!Ej8_|zKon_9D z`I`?T7D?GPLmhj7+%9XCO^V{=S~?^mYPEcWFE&}3MyPC6OBpE|88zADD}= zF;ndB+C-{G?v}0H9Y4mK?=f56W7C>12N!??k$wTig#UaIyeKHUj-fx-uiy_z0P$kd zpHT_3d-cL^SO`nGsc;aCqT+%8S)FSs@B~Qx($VqB|5E-AzsvRhyudEJ zTFl+b(#o}W`zP!~OVx7CS>X7}x22{sy~&5hoHj>&!!*>jQkG_^xcd3Ga2y)q{&0w+ zmq#H2Q*4-_hL`E0>uYprRpqKtero2*ZQIL?8NH>CjtA%e&J%X%cGo4ncH zAolmf{l2I@fet}b2*TK|Y3-ly&7xBalIqpOD{c5??$Iz`Fab%07UM_WAj4QQi-8=_ z76GVuv7z-o5+P75E=onm%Yjj%N5pvT+)h?!sis_CQc!fuwo3We$vytHZ`auNEv}Ga zQ|IL5k$}(6A@*ri;*j=pEo!xZXrVd!o$$iW6TR>9jb)RJ?Ghesdvc>sg4Ni=c<3TZ zDPYFtNG@AMn7XLznL^A<{oNGgyT#R=#Vo}3MS?FjQ`dMI}i5l)mbL#1)r zqFr;xVq5y<@rhi3*UzI^lBv8${x?6C@Ix$r7tcRko;pKY}Y(4RN2j+w7YnAGmJWxmPSwNC3FZ*mv(N`t}?By`6|1fuh= z^rxy2wCSWXIZG1Q~U7?N(0{n0Xwj#}MphKf2wM`1a!2QSm| zgds8^v~E~a4Mow6R^f3(F%Thv&}47|s5rV#@s|P|42287^6t9yzl#i0edoot+~Ie( zb@St5etIc(v!#EdZ?kmBVey1^cVWoa{?U`x4Qtun)|3o-FPS5pb>gRwyCvByMp)T* zIiEMQT*LG&qXuAf5S8d)Gk#?T#xYT9#uW3$R8-~9pdJqPIAz5c+1@vzkJC988U#h) z8EZxOC(SFsMI7S$Y{*}6M5#g`7;qY0*ZPY6JQ^2l$&de|k=9KSCF%+TS_*`wgpdip z6(rFHjMVf&r5A_i<4o)ystCy5V=Z~BDDsX+ff_r{GE2GQ)ZtxszO}bH%S{sW=l5dw z?Lip#JMZ5+BqSuaceUXq^=;`1h$bR1?h3`TAWB8d4j?{#l>|r*cFZ@&^|TUDA;J<8 zMJB&cK{fsp)G$jnTjWd-Jd{qd#g|+DT6+d~y8F7`9RK{a<>Tq&|}J=)yJ=k254d!hHXdbcPb{`7<17aGJxZ7*2F6eqTmQD+M1%5mDANBastN_IV6c?_Q;+A7Aya}mokkEM(FCu|V{t!R zM)yIz17<&XE^W?_@4hw$1>78-8k9}FGrdzjzuF#IYF-?uGosYnTqtX79-nD?!3?Kq zp!v%voAY~%Wj=Fx-Gn&Xjr?87yrQ5}VMIpp3?3b4%o}+HAr*nBk-BnUMS{ryBdWZC z+B@`|#>A)hL(pb{1~PY7oW&W%p_Bs0#b7F71{YztIob?H$7V!)nwx>7CP9L{1)9kK zkdP$G>Xb}F-ee7TRbE1M0y^c1kNKsN>spl_xlP5m*?Vu8ONukJ(Mke4mw#_>kJtO( zJj+}8_j~EqIrq`sCVr=5EH>x*4en_oEFRHgPV#WR8XRGcA4dND`(kl@>3p+jwy3}A zyfM&s!n(1gE7KRREqqWor}x=fm2pnqSc)*E4}iNzO=6r08d;2GgGFh(zF@&_qhv1VUvP2JM7Wv{CPtY7kpw@KUUq}sm6JqZ@1=G8=+fVc^Y8jo2c;p11Xq;U(P$rzw04|Sg*ilGcY>w-4?9;{n?W+-PV)Dz#-JIU0fqVLTpX3x6fw70X; zNKb+XSNPoBtTvXBJm?DidAN6%9QKCf`j-Y@C6#_r3bA_D5+V>;=WrfEgfs&*Oi-pY zi-6UZ@aRGHeFq11lmd7u6v!(Ie#Kmna9_zjw;U&*K_YfA zY<3gBVZ4Hu+x)&~aQ>zPr=rR=ArVGHlp2L9;6SG$MOYdEcs_i@!0f?0oUl?e)7Zzq|CHe{AVh zJ7bLlqbYOB<1Df)=Uu-7cwRuJFxS;4@c}F`vvY`}l+0qVnsWXCtU_4ByzYlwC;>GL zHf)IB%h?OIEZkz_2>TPgMUTq_b&mtjWxt+26AC8+;d(coR}6$lQ@J4ZfU$yMf2J7l zH9g!F5k(3t!Hb$fICRt%yPH<`PTj~G4z6!hk zcUDFp^!LGoyPuJ_{|hzp3!l2Ha(aa4c+|OPi&f8#f~$0J=2aXVg6s z8uA)T!Q7&Vk=8~6_RMHUhaSs}x@wdf(0s@N2E6~4%>F|yUH`<{_P;-QRkO)io8AYF zoAcXye>di;4&;}*K7{W&$yR>)yrE~#vyOl_Zvo9U?jvGmM_sJN)i8xKW;72_VrtXqjghOi>v3N zTjL@#OP>El0h|DNYLcHe6D0is}ty7AuD+qOEsj!tU@c54!!tNQ020wXx@cXyd3EScF z8>zK`|58K64=mCb9$0;~DzkhXi)L2)xIxF-zWmE+^h=?6PZUzIIhH+hxEI-LCc=y1 zq8O7(rsxw*BN_%m8GvBEyy(HH@I}!)Jku*L$@08o=JX#M$zyBwI=px(ooM#}0`W%~ zIJOL}I5Yhj0*OVEX=S|TfN&)y^5Un+9nOO7`Scn+aUJ8Y-%F-`JNhMiElb($_iI9O z>fbNt^IH=yGvbKp@`3?&D|d-hWZWN|qX^u%S#en7sTmAmNv0-hoJ1fCcxH)D_b>un z)?-6M#*3oASgE{4=V{RrOJ&Wel^MAccHtx_enz5<)6#t_bk=M&nzA4C%^t1 zu6O#Y0|`alVp(*0#qC)c>M{(2GePSh(1HVF-TMrsP@d=z(9@c?drYM%3CzQo-T0$% zsG7x734H|xnkO2;y>*S+hvuJ*Uan#DUSgS9b36au{r&m#*VMns4H+jP8_!!rEB$f1 z3d`jN+O}ats1^143-6FC2rXJX6Bj>ScUT+p{ZSi^^w<$GqbcwrJt276^>c7r>PFaW zAkejpHy9HWH?BxW)nG-vXe3tX?V*%dx9gh<*Skd-e|25N1DNM44=K;j4_dhUvt}n+ z(l^<@Tr8cAoYP-Y{I)KdBWaAUE7F_cRJXU_h{05YaT(QPWMCK#n8(5M7akJ;vUKu= z6O$6r3Lu+hG>RNWKS#wU>>OL8p3yt8Ow?vR;Z@!$U4@-bwAWBPnCyPj66h|TYdY~R z{$+NaUz1Z)WfRMp>4#gPYyF2p-i4ly3HFw;4wlL4d#wC%L~qrh3A}h78UZ0t(u}&} z2BR2L)5krobR$EIyQ=uYv`?_a8T3$=i0fBAIHC>YxhLKx^o`MZ)?AUPwc8u*TQ z3GvFy(ga z9Ri|g0W}0oF&W4#LFB{}Oa%i%NCBmZjLkD#iET~wGSkX7uAt?D3i?al>bCiHTQpPyBR%uh9Ap#XZopKS_Ye&Euc+t zu&8dddRTQd?xHm{G z$62i8`AZhGzPngkyedS@mWzcNhj5vTizI(flReknB?clDp!HT+g|OV+F=j?3fqNB>-fr08t`?ke{gHD(3>JCN7<;UTIEtqL)^{4_ySOcQ0 zW|2g7@-QxQK?MlfiCxqAOy3Mj#{ zsU$+DPSXNU=_Tn+8?X5;R<5b2nXSmMm7sP{^C>d1*|iy7lD)3K{C7t4`Ip)ylc!mI zqtew9n|psdO~1~zl-aDw2b^Af{dYF8S`_x_`tmoM${~$xLO4`gHkHLZbKHeci69Aq zLu5z=)0||grvudbGzAdhtyaU;!NpMtE2%Ec=FH#REY&2AZhron2)emg3G#1|m#wnl zzWuvzZgP_5I$1ikjtbkVi#7I%V;7vT*=h}HkuIN$%X z(NYQmNhxN=1G$pbH-Jc7STq%oky|RJqY%8c?=Y!gPNIf`kg|u%U^olRp284!rCYlx z4va8S2>XmuFk}qQV#$M3;8HHk=SQRUab1u_VoAv%(WWbFOU=Vku!1<<69^+9IgZfpp@R4?}Q{R zmdC{$<0K;=sI12}(!|D<`kFJ8G{BJ#{DKc(ty`pj(TFdY(4O-hmuy=+^7?WdF<<&t z@@u-PV?E=C2L|ajmw9r&e-0OuPY>QuQWo-?d`;yjB-L9t)|#Ark4o0~mQ-G=xa$nXb2qPT!sucv+^9%R&W65mUNBW>~TK42>B8i|4RW#1`nTr3Zw5R`RCS+V6 zbp}by0MbbfqzO7bWFFFdA6H1zBxD`H))+71AejP6f)t^sfC4%Y2#_?qCOR`CPa{xq zghZ6iOb503r~m>JLWA#-aL9m_VUK=!jSQr6GRl~bPf zCXbX0IAd<<`q@l?ISE)N#|yJeHQ=%pMxDe-`*1Ksvv_Yl!FnBD%Jv!ZalzJejpooA(1;uafTyt%>D!)eNj z96Aw6)*Vl|IQoP8DeUUst4^mjxK7m1F`AU*F9=L7iRw$zZ%z#U-FI^h^z-%i|M_e0 zuD2h*J;fpyI5#2N_Y1A*_g+CwO|y^ysL97pa2hRa790H&7dnj0@E8_ncqByk^=o?B z?$_AH#)Hkq1IZIS$d7eO==oz ziqUuhkU%V<)qrGp1K(hP8`?hycV|xroi#FH#G>OhX8f)Mw)jRiL?b)6#6!zFbKXd6 zutqJx>lJ?iD&wOdl*$;ek_L4ar$+jN$&IrHp~aOd}uo2OL< zc{B6)~Czb8Ki%r5BIbu{c2@^ZAU5dc_GbZrVSqA;TUu< zBV7oWsPRS^$TE=Y4}_#8>E*-_@qG>+KtbO?!^D7Mh=NA86Gty~Vj{(B!`gCwfaw&| zJxVPT72m@_f=$2qPCNmC-bU3xHS#hq5MK?sTj;uzn328w{mOK7QZoRlTPU2Efg@;4 zt#sgo?G%BZaRghli-iv(6IMNiMbj=MAb^3yYLrBG&GZWv+Ia8d6l5h{8?G9zP_JYJIiASM=sa$x^C_^ z<}ZB%jtBMH+Lm2AT4diO*$@9@lIS&)V4N45RwiODed;GBHdtdH#{t=L39h#Vqb;a* z9*IP6J?E8wpo>&8%Wk+Y2$ruK(clv_0%plV3d%*PAVgms92+Ogl>`2ZW1ZT``qf@v zIaXP_iZ%T}cM#hsN)d}EtTfI>;z~s zZ7pe?QZPv#n55-B2Rpu+_?bsHe=AHFCQ9wjjY3iRBYXV$uB;g0H<}X2`v5noib}Ty zp^{&4o(%Ad=VLR|5^-6}0tQuMW9R+-o9Pdn$p% zzW3laZD69XD8aG}kR^j~3l)?+5`gF8BJGe#@2NPxl;v3Hx3gG_c}sdSr0u`*M=~ZT)I($dJjy9MKgtu;U z(zB=(_%NKSnua9M^s37kC(|%QizC6$1->{qeMz?| zGvMalRgJW9HqHC=*D1j7@ZdbqaPq)!YBSgVq`>_kLZXUvOwca&OLp1|UVTO)3Z8ZC z_`15fVjO|xvEeX&z+G*iW(zOI{hd%u9l^{ik3KsH5BXlC76K#{jtCYQa)<_j04f#V z2^%@@Te(sX84Y@$q0#82#`Q05!%K7|f z{}`GG5K`t*{HUMUACIVmNjOow&#Gbp>E>Hq2rn;Vg{G!Htg^oB^nG*p`{-)PJGPP3 zS)$`$TYD<-WMyIe6W>vT4GU`wRf#1)qpw(i*(6zWfzD8uhQq;90fizEMNkK~Cf~$m zWKj0q@bPy2k;R|b>ONvL3P|S-QU@iQJzZ`{Amjvzb7?e-W=9E<;Fw#*%!zQc3}8ew z!D+~!4l3axVh5Yjoc4LoPtTW=VjQTGIHhNs+TxW%fCfYDU8bwqIjr4&7suN#-@OcI zkqS(Yty-+h{(8~%*@Qg6cxu1y$$_ww&jdbyyXRfbAR3|*QKM$QN#_Jbu(y_w1tMJ< zQZ-Y|oj4OLIQo{=S4n#uqF<_NQUTROAUz0o{$V6QI>anV6NJk|8YhB4I&mWwT*_fA zHF{#>MU+Q}UUo5`I~ucGvDlp2FL>v)H#oiicf&s*(C^>7p#2E$HoO z#;&0{WDx?r7d~ zJ5-L;8WUACWN;x#p#vKQYl`%R(;*OxqI59BPWpsk9y72SvqcZU5SLkuHVX;6oY{DE zUNsCc%uo+;0BN9ztukDoPk@8-7D*09NEWlucLHeb{8$Gs>s0%fFV@;hs#GNeKW_+R zxprX%o%O$}ZkC$lp1d@1Htqbgzqffya(VK|A2q4_+?qaxs-aFS(aJlMQBZ>yo><#| zakhhpD*bfv_450Bc71NJ_VSY-qojds(^2ax|H`ACXYE$5dMxeOG%S6DVnn%mXbDYn z9Vec*!TE$qQ3Xu0fa?K@4ziGD$`Zp9{4EjV^xcW^4+2Rw0{H|iIpK=U9tRIqwcJ~eOJ*unX13mz4losGS{ z4(gVY?~)2AGjBWi=6xW#nqpqx-%2eVo81<{tliPJz3{{g2-L7mjF|)ipU{=P=ID=3 zB0J7d7lq&-BK~cmf_kR}_W(&A>);EIl+S^pbi|g~FwGRv;lhaL#8$odT2pCHNS_%| zi=`zHUx_tN`;k(ww!u^;j}eeUod zCy(TQTzZckcMgzwqN*&>8qu}52`)8VcdWqFv-o$bU2=bqJMbmr*docJn^t42Jd$lv zjxExOxjivwIZD9k(JNKD5psj5Bqic-oDzAt;uW6P zfiEv$@#Tfo9u0YOS5@9Hf=Eavav@3K23to9LrHB37yC@zXo+?su5d@=#7a11&u_!o zy)ObGg)j#6B&NC9R8Z)_l(sg-T9@zT&cxyfWbI$e{Dq$JgUhGK9*(PDa?;Kh@h-qU zyDinlH7Qej>)S;F%y1M|;+(_GvrU%3SE&$AT#^06(7}iUA>i`!DZW%l&B#xflu-W% zamDlJVQ9qt)MX8GBJoVKB&mMh7l3S&Qd$ls=<7Z+We$WeHK&SY4-5ftqkCVR@2j~y z(Owrh`d_4tX->E=9aO|mG<@zr>;{^+$Kx6&@~rrd@-gTQVBDecJaA0 zG)60!L{1VxOMZuBiV6fH<5E&E4P64SfD=)ka1rPg& z**P_7V~^vjayA;CYq0EZ$Vf_Fb~H<#*fbw-84JSGa8IK}`6Wx%6B6%N4|DKWBY;Xz zRMf@A6=S4ThCna}&R$C9o4B|^?xdRUjXH`b4uNK7I(0fKs`uFmz{Cs~SCVWmrGN`V zCIO=ciKV_8O@NM!`13gO`LwXldaC0co@I z0_x4D_*EF!%+HFQ-+d5&EdC@qodfcPTrZPx{j-A{hgc$NMeU;+6ifOBA0w_eAKz@` z{d@QC;3a;v_$ui3LsrAGe~i*+x&~Ky=cTF-T{mZAFaKTtyFPe%yJYY|9*?Hyck2Fq z>rHaD*Jm^HH0P_Y_xSDf?qG)FFn$7X2_xQa_*CXasx3%=R|koG0ToJ%d-5Ym+;NBy#(jO({TUXn(U;tuTN0ccqMd(y@#z$pT+|5fgj z1;yn_NV~y%-pXnbq~?$s>Mc?RAp|66DKca?WHlIMRm z6MCKf@6Z0-yP%t(F5laUlc38B=ezE!{g%9dtBxR_+x^DXyUpQxZ^=)_es8uqJeNOY z)8$k%%iT-87+4r8c(t;>VdujB3U1g(4p`WtyJDtj1bTRiEtqt5J!vjf@XgmI{Cj< zx>p6@^b^-Bd!EPY^b1Z^+>S;D;z;)|E4Ti)e}BgsybL_Y6EJS~*SfDJ@N1P5-4h>7 z1-(B6Tp#seBj3n8m~n~V9RCI8ET@}O#wg@V0CmG+ePH=92q3zil)h+P10lR!2~!Ss z;r(77OpwaoSmhhZj?M6{z%usb2`&^Xdg7{}cIIX=B(xnU<-vP=QM#jpbp%b{k@+z> zhQRSj2Pr0jgWiqgtgJUF826>)6X))mjSJtOkNc<4$#+yZX3k!*o$ot^rQque7A|!%09qQa z5=AQm6aYv|xqLQ&BPoPhQS;5Z`dYANnoNW*rjinkD-)!$y~+(|GY8X$q6vxgdV^i9 z%-mZm2?)(?YO(eFa0?sJ5dH6>T>hP|=#mKtxSpW@ zaMBeR@b~QC@!e)nK%3C+($^1xmmT;AfBO6UrCXQmA9IjhBl`U+emN>n0=Evc}qcUUp2nZJlL58Fu9s;*`lfCA%#y zPWh#sd4`+{Yjly)hw{nQ6Tk=|^I@!dm_rV)u(v0=eW|TbXI;D%=dlbrgUS_)yk>XBMdBliyJF2LeCQ`2*p5Omk|gLXI|Be24%>1nb>b zr4WKf4}XU*j`zxDf7s%^i_BE6O+(GdM(sQYC(YB` zC{p)_?EqlNBBQPXwmudk#NlP%pBz>7Kg;R0@zL{{v8h#Uo zA}3Y4)u@w9`n>z%puiXTAS=r$_PCmQrTO~$9Ci?F_t}h@!y6AnSE*r=5K?mVQqf^8 z-?8EGf7ZrlK#RdD2m3x<)XI(K<_qE#qNT);!HH8%d@#C@KJ9|=e5NMa{_W_6c^Zs7 z5+AKD@GndF=sh?Wd?PVtObCmSi&_ZJqetdqZaSNTi<{*Z`@AOiJlZ>Me`kH@y8Au$ zK>NeX%e!N1M%7E5PRHzLD_lxnuKZ8tM)&LAbIy3>u8+NcG+L%a|TsXM&x#cC;mkh2mt^RY5^9wtOab3Tj!Jv4YuO!mB- z!98^p3(B&wOAW;-aZ=A$M?PtA+>_p|Df21}o@6}BFxe^fD%$KZe0VZ>PxyzOlfKgr zcCzzK)2j0xIZI<%dabwQp0mT4-pfzu1~wPX!H(ftFE z#3~bGM(+`iPReD;@f+|Va$7s$oe5Va112Q^qL2bLw;FGcf$t3&g#QI!An zsRkL-%BD(UIlP1(S6Ud5mG5W}MYLlWxCCds@c8Lpgq5*8tHI?5o;?#elG|b)))TL@9Nn`jbR$G2|oX zBcm~9Lejm%^w;9AM8DO0RToaYEwP^VVs2wxCZot5`zdp>C1taXu_n3?53EQr;-Y0a z7H%GDMpdTZ6n*kt%xkedo&8uG33O_dvNd`IijT0i4c!Jk z;oEtZIL8sq&pzN3<+m)bIoRH5=)dXu_;CH`*ePrG`A+C(H)eUi++8mwdF!mqdqil# z{6Q{mrl@f9l-Ex*`cp^4$x;Y#r!xlO8z{1#Gwp zy-?qM_id`v@*VPU?+jI74BTMH4r!K)Kkocm1;m-$MM;XXNz)9{YVEQUyxt~a6edH= zW45h6@h>eUQ{#ukw+^#SS%+l)j#NIQ=rU^jwY+LOc6jvKW^#XVt`DtRqAM=0R5U&* z0Uh`bZkywQVffB_V8RBq>~dl_@01qs=>2rCf-lC^DiV zA2U~WvVUPqE5sv9ZC}7;WDm@1HQF>tF_`r}9y6Z0MLAdBEQ?&S+&`>9I@uyfsLS?Q zF*e%9ie8AURp}<1$(6I~0hTwM7ec1Sr@T{H4jc`~@A_A2e|$TcXh{1?mupNSfGKkJ z?CfKw)LU0;hfmTIvwO#yehg!=R?@XE#>Sc?Cnqu_$NRm!oKxK!R(Ksr$TBAn!BVi< z_L!(B9<2b7Qm?S@lM^ILDG&GWBbLALQZxiJ~wOv zGo=$UH!|s{Kue>Z$kWk4YFOMSY?V&3-iIwe#CQ?&)$T;uff;}ip#%jnBhcD}m#S`Fi4+;|2K1k2>HLK7{01=tK3Zqqj!MMp`WZ^jJ(J?(elSC^=v$_!@~B=V zT&xQ%1Vl)Ni85(*k>v;UhQ?4%;Qg2`-^n1SMOmm16@!`3fSz*C;ec%4Jt$c&rt^V` z(Zj69w{35;vyz+NHp6Tq-rGKXkv3n9&hpVtTNiml7w5Of{Akf611yGiW%r`ZXAvS& zidi98*VuW(=UTAQK>ZGjJ|D+|U3@usI+%pb4OCGC3L-etbJRLML>lnnf2|sDXz7Uu^t2}KLGkwi zqJ=A?oQ)FG!MqJzO;J6h?=i|vhiXoSbr$C%4& zgund=1=lk88{%_=tSTRUEJx)THD4}+&XtJZJ3dT(73@UW4UBLRYZrWEzxrT8rbR)} z64JuA_#bWTP|EI)z6Q_KPLCXE!PD<@vLv(U4gg*$sQ656TXEekrAmizN0A6xzCprK z-X=_MVUWcZGpeV+6Y;Z$=gV62ghOV9b>&h8=jL#5CHA)jZTq{pU>@RR%xSKXwHRb!3MNu zf!YM=+@Af{QX{pop~dZ3<%eobe0rljq$dAS(Y5CTh+?Bbi7TME<_$Z{4q+qyjeI%y z3@%8|XQ1nAJRrnT82aAC_j_n?s17eB2Q=mKVYpmEK3ABu8+ywA`0FI0Cu0p-y=VL_ zGD0>YqHJjKMMlxsq3xK=&ia3iZT2!I8Y+aJadOMb~Nd+#6*RmP|QXp1>QjeT7r@Le8I&H z`69~2jZw@)b5ty)6x{J;@#FOaXxl(MO-3)Tw)3Zd@2yA+iPK9LQ+HE0eTkAoKG=++ z5?yIH6MP_?XQ%HF3KHn6UGKA?XOI)4ObLdp+2m$E&VoqEJ?9Nm-Nu`+9D%K^Y)JNb za3rHZ=0%=r|FD61TG_}fWRT?;Ov?NpFjRkoLs8E%--=f-QG9z9@CKakmvQ+_r5K0BRNW%GAA zght0KK|`^}<82|aa0gJsCnd(jG9L-Vvd$ka6H?j$B2;=_7*K=U}L9bze4f0MT1T5=|x;OXV^kw()(4LHmrz z!CXWk-GCF-6P}c2H*pky80AQx>c2&h5d1NwKK2iwoS;W+HqN6p~||E@5Y(wD3pd4N@Mr%H4mE3{y!o*E8TRDk9L{LC4zPp8G??z1tsAY z^1`HS0p+9jtPKEsW_NbLooG8)Q$vEXyLr5dgE$P8L!MLFG%{U2LzTwf()8u+x>MF8 zXcmF(M=OJG5arGSIv4=!)mH+KNRi=Va7l@Y;@(jpFAerFR@g~w!#gDoGYo7Bf5Yp+ zf)0scAsLDoA&goav^Z(3_N|UF{44Q8#aaNZ%XYDVU?GhFmv4+ zGKcn$b`N7ipO))D9MMA7j3u@%S3Ls$zYI#x#6}6*^Z}VFneS)Iv^4X~#j1_II6B$` zlS6}THN*9l$)ia1-j^i3_~yn5dCecqb`JdJm=WV)+TD(}5)N9XlBo6XZJ3_d4i zGLQZe-T#`5j12y+Fh52sTMIM0&YW`Jq!;V(BThn`n_q`E3Jox}LWI&OO@xP7z3J7i zKy!^^d_EG40)euns|*~ZOWy-sSlfzhlKt{MXD3RtDzd00&2uiQJZrFNj`8ObqYVwq z8Olbf{p~BS--zr?FDa&6tvw4u>AsqYh+oVaIYlbi@%0^J054<~2F(nyx|Bckp_(+S zBEYDs{GYR!j+^SA@jq?KTSZ}~JtjPSTy~mDbMLhVG{M53AHlq8^D7sWcT@*HNs@J@ zl#rFG1+W-N6_=w;e;7&J;Ar%)Kv);bbaraONmCQ>b~XU zp~QNvvux<$$6fZVc?n{M=YOUciI8`iAf<85r@IRI+ z;w5UaOP%rhSl-WaJRwT4Kfxe*tZTIQW3gE9V>xY-QLL_p89_*l$wHf82c3?w*Y=5e zj}Xi&G(s{Z*w%+GS5JvJCIoD^icaL?0FG*hG(6YQQPRxU=|MmWSTb@nnx2wxDAJ`+ zj`yju-SWcM3|u{Dpa1+(-cbMEsClHaO*wJ|QuF%lBZj0&0k^Uto>X)V%ie8VWb-ty zC=&{+DTs0nVJZlH#ms>P))GALS0{4SJ&(X2MIf~!Po3*@R7(X03(+Ls=~FhtL7|4* z(Z1-oh0I2j<1|+m?StNX_g^%#O0YZ=Sg-TMB~}v2Ks}=R`+5V~w#t{u;wKBTcGb`2 z&&7FDF_!%_YKLpi9xZuxx%F)n93KlMl8|* z&&f(Kru7vLF1VdHq}D)YOro?)E%_mIR#hq!6;p_y4Tie|s~2x2f{6d4T}`+ZE7 zVJXnsKovnAh%w_p9DbaqmPm;rp>=+)HF!_?VI3sl07?sgl`9PBXc#a{s_IT0mK`X%8m()LF%OnQ)hINvq}6L-_!H!i$#WY3Qv*3 zy{MeYx?bX}h4B>9#QY{&3kcGMs6Q$e8uI`D|Blfj#euLG$rvBE;R+7dOmofV5t$~= zu`LFY7h>$DsYBo1eq$wVPSbrLpHXjV;%DmjBGddHjoS`EhDmFbD|ql*c^S`+;&!5) zu%;KE77I~IB~M)eq+(pmy##1s5N2{-YzWeUx5fcg0Kf1Ue&F8Q((ykP^<0=+)Xuj{G8$RJB7NxvSuF(4 zetc}&ulp4^p|+beTWaefk+0Mg4Yfqgi(3Gml>mv~4cu2)h1#GF#A_QhTUGJ`6#GGKQ>SBn@u^OvV5#@g6x8i5|FOhUCB1+UdD*C}}22jV~^@Zr-D?EfR_+T)r2|1UGl65GtBC^N&X$URcb z%w==i7;-6>+;WQ)h1@UOTynn^x#un+BoSLGBIR02R?$Ty3Az2=pYLyfc_W*5&H5P_PZ<}`h? zTjkVH#WT@vsHqV#mwrz5)qR^THBDW%r+6hgl$+ zb>@2GslugGaJ271Wu&-@J(VV-hy5>d=lwbpdl`;$|J8^3)y0peWr>D*YWOIhd5(Dd zHP0f|{Tue6#Dom(LXJ$r;JDhUNoBLiDjR?K!N_B3-+?XRgOVt<7f6s{7v*K{kfr8- z-6?NPOpvW$4bXzsgwE71P;0nb1^AAzUt*QfY`8M~5_0)Qg4`+d^jqmpm*jsey;Xht z&|6jf(vPpFw44S%9C`HUS7^}Ga9PCS2c0y3-v$&R{7Ilsl91{QORcE(Wv3|fg%8nK z7G%mHI77go*`!_`UsyL38LCEsQz6Qgm$J>=Cu_Vj1@^J-H*27bc)WwvJR z=9irA(w`|rx*dMt<1k};*w=@eYIYG7mqikUsM!CUEKULCq(D?)GhfP=+K%yD3Qi!0w{Js6$%&tSaUv(_ zx}NDenxo57XN0Sf&pwx{S*w;+|6=TSZEf;C%dD2(<2? z4IY+x0G@jwmihj=5XrDTvn@xaws7O_gG$$Y)uc0+m*xjly-wX#C{<0iJhG8|%jx~> zR`w;GMOT0}(Z6hxt9{D{k)PFr{&P#aAng zzoWd=6>WGybe*^Rcg|?POJCCN(AaMDe9)mA^ED#WcjQ^-%0A($ZCIgZIvFDiin+C0 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 Date: Mon, 21 Nov 2022 21:07:43 +0100 Subject: [PATCH 29/83] Update .changeset/gold-yaks-join.md Co-authored-by: Patrik Oldsberg Signed-off-by: Bogdan Nechyporenko --- .changeset/gold-yaks-join.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.changeset/gold-yaks-join.md b/.changeset/gold-yaks-join.md index 6871948c81..29996d1f74 100644 --- a/.changeset/gold-yaks-join.md +++ b/.changeset/gold-yaks-join.md @@ -2,5 +2,5 @@ '@backstage/test-utils': patch --- -The test utility for PluginProvider called MockPluginProvider has been created. It will be handy in the cases when you use -\_\_experimentalConfigure in your plugin +The test utility for the plugin context called `MockPluginProvider` has been created. It will be handy in the cases when you use +`__experimentalConfigure` in your plugin. It is experimental and exported through `@backstage/test-utils/alpha`. From 3355c5a5f1dae668760d998a9c2d4732d0ee2f77 Mon Sep 17 00:00:00 2001 From: bogdannechyporenko Date: Mon, 21 Nov 2022 21:25:26 +0100 Subject: [PATCH 30/83] Incorporated the feedback Signed-off-by: bogdannechyporenko --- packages/test-utils/package.json | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index fb8dff4192..1734a17f6b 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -5,7 +5,8 @@ "publishConfig": { "access": "public", "main": "dist/index.esm.js", - "types": "dist/index.d.ts" + "types": "dist/index.d.ts", + "alphaTypes": "dist/index.alpha.d.ts" }, "backstage": { "role": "web-library" @@ -23,7 +24,7 @@ "main": "src/index.ts", "types": "src/index.ts", "scripts": { - "build": "backstage-cli package build", + "build": "backstage-cli package build --experimental-type-build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", @@ -60,6 +61,7 @@ "msw": "^0.48.0" }, "files": [ - "dist" + "dist", + "alpha" ] } From e91e559f3a5fb5837c1103f0f74132e42ed99ed1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 21 Nov 2022 21:21:28 +0000 Subject: [PATCH 31/83] Update dependency cronstrue to v2.19.0 Signed-off-by: Renovate Bot --- yarn.lock | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 3ba43af036..04fa28dfb8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18325,9 +18325,11 @@ __metadata: linkType: hard "cronstrue@npm:^2.2.0": - version: 2.14.0 - resolution: "cronstrue@npm:2.14.0" - checksum: ffbceca5211575513b37a454253fe7aeb16fe841ed12c1e8a2241f0e55f46a72d4cb97fc3b56aa6bfc58c7d249f8c168f89bfd2011841f237098f86f435f6fcf + version: 2.19.0 + resolution: "cronstrue@npm:2.19.0" + bin: + cronstrue: bin/cli.js + checksum: 8f51c4c5016ed696569aed4fdb91013a499c3ace93cc5385dfe41d15b9fcc5f284d7eb457fdfe2fa4b05a3849f025ba8a3ad22197c40453efb0ef94271b3e843 languageName: node linkType: hard From be260062ea771207eec6240b8b26b0b6c7d01d59 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 22 Nov 2022 02:05:24 +0000 Subject: [PATCH 32/83] Update dependency mini-css-extract-plugin to v2.7.0 Signed-off-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 2793196219..36c8b98676 100644 --- a/yarn.lock +++ b/yarn.lock @@ -27916,13 +27916,13 @@ __metadata: linkType: hard "mini-css-extract-plugin@npm:^2.4.2": - version: 2.6.1 - resolution: "mini-css-extract-plugin@npm:2.6.1" + version: 2.7.0 + resolution: "mini-css-extract-plugin@npm:2.7.0" dependencies: schema-utils: ^4.0.0 peerDependencies: webpack: ^5.0.0 - checksum: df60840404878c4832b4104799fd29c5a89b06b1e377956c8d4a5729efe0ef301a52e5087d6f383871df5e69a8445922a0ae635c11abf412d7645a7096d0e973 + checksum: e6b111d4289132bd496286eec42801c74c83af7eac71af630a5babae48ca65377f47d8b39e1f0653b449e68e67b57dbd0d36917242f08fc3e7770e70c0cb56cd languageName: node linkType: hard From 90a6fe68ef162132e9ffaedc9c79fd9671e38878 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 22 Nov 2022 06:55:39 +0000 Subject: [PATCH 33/83] Update dependency sucrase to v3.29.0 Signed-off-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 2793196219..9c6aa24b31 100644 --- a/yarn.lock +++ b/yarn.lock @@ -34793,8 +34793,8 @@ __metadata: linkType: hard "sucrase@npm:^3.18.0, sucrase@npm:^3.20.2": - version: 3.28.0 - resolution: "sucrase@npm:3.28.0" + version: 3.29.0 + resolution: "sucrase@npm:3.29.0" dependencies: commander: ^4.0.0 glob: 7.1.6 @@ -34805,7 +34805,7 @@ __metadata: bin: sucrase: bin/sucrase sucrase-node: bin/sucrase-node - checksum: 6a2369c140cee674988ebcf83538f38b11270e47ebaffc811baabe1db3fc586f1a357d4bbc66388a6b99054ba06a08f31b44b764e777abbd457b9e29332b12d0 + checksum: fc8f04c34f29c0e9ca63109815df138182d62663dbe9565fcd94161b77a88a639f40c46559d0bb84d7acf9346ce23ea102476fd9168ec279330c7faecefb81eb languageName: node linkType: hard From 7ce59cbd3ce2d4088ce60d36cfb830e92b99a140 Mon Sep 17 00:00:00 2001 From: Thorsten Hake Date: Tue, 22 Nov 2022 09:00:28 +0100 Subject: [PATCH 34/83] renamed refPlaceholderResolver.ts to jsonSchemaRefPlaceholderResolver.ts Signed-off-by: Thorsten Hake --- .changeset/tender-colts-greet.md | 2 +- plugins/catalog-backend-module-openapi/README.md | 8 ++++---- plugins/catalog-backend-module-openapi/api-report.md | 4 ++-- plugins/catalog-backend-module-openapi/src/index.ts | 8 ++++---- ...r.test.ts => jsonSchemaRefPlaceholderResolver.test.ts} | 8 ++++---- ...derResolver.ts => jsonSchemaRefPlaceholderResolver.ts} | 4 ++-- 6 files changed, 17 insertions(+), 17 deletions(-) rename plugins/catalog-backend-module-openapi/src/{refPlaceholderResolver.test.ts => jsonSchemaRefPlaceholderResolver.test.ts} (86%) rename plugins/catalog-backend-module-openapi/src/{refPlaceholderResolver.ts => jsonSchemaRefPlaceholderResolver.ts} (94%) diff --git a/.changeset/tender-colts-greet.md b/.changeset/tender-colts-greet.md index 77c1a8f1b5..ff59bf0bea 100644 --- a/.changeset/tender-colts-greet.md +++ b/.changeset/tender-colts-greet.md @@ -2,4 +2,4 @@ '@backstage/plugin-catalog-backend-module-openapi': patch --- -Enabled support of resolving `$refs` in all kind of yaml documents, not only OpenAPI. This implicitly adds `$ref` resolving support for AsyncAPI specs. Thus, the `openApiPlaceholderResolver` has been renamed to `refPlaceholderResolver`. +Enabled support of resolving `$refs` in all kind of yaml documents, not only OpenAPI. This implicitly adds `$ref` resolving support for AsyncAPI specs. Thus, the `openApiPlaceholderResolver` has been renamed to `jsonSchemaRefPlaceholderResolver`. diff --git a/plugins/catalog-backend-module-openapi/README.md b/plugins/catalog-backend-module-openapi/README.md index 44e0307ac7..6b988e15f5 100644 --- a/plugins/catalog-backend-module-openapi/README.md +++ b/plugins/catalog-backend-module-openapi/README.md @@ -17,13 +17,13 @@ yarn add --cwd packages/backend @backstage/plugin-catalog-backend-module-openapi ### Adding the plugin to your `packages/backend` -#### **refPlaceholderResolver** +#### **jsonSchemaRefPlaceholderResolver** -The placeholder resolver can be added by importing `refPlaceholderResolver` in `src/plugins/catalog.ts` in your `backend` package and adding the following. +The placeholder resolver can be added by importing `jsonSchemaRefPlaceholderResolver` in `src/plugins/catalog.ts` in your `backend` package and adding the following. ```ts -builder.setPlaceholderResolver('openapi', refPlaceholderResolver); -builder.setPlaceholderResolver('asyncapi', refPlaceholderResolver); +builder.setPlaceholderResolver('openapi', jsonSchemaRefPlaceholderResolver); +builder.setPlaceholderResolver('asyncapi', jsonSchemaRefPlaceholderResolver); ``` This allows you to use the `$openapi` placeholder when referencing your OpenAPI specification and `$asyncapi` when referencing your AsyncAPI specifications. This will then resolve all `$ref` instances in your specification. diff --git a/plugins/catalog-backend-module-openapi/api-report.md b/plugins/catalog-backend-module-openapi/api-report.md index 9dbc899dde..7294fd5936 100644 --- a/plugins/catalog-backend-module-openapi/api-report.md +++ b/plugins/catalog-backend-module-openapi/api-report.md @@ -14,7 +14,7 @@ import { ScmIntegrations } from '@backstage/integration'; import { UrlReader } from '@backstage/backend-common'; // @public @deprecated (undocumented) -export const openApiPlaceholderResolver: typeof refPlaceholderResolver; +export const openApiPlaceholderResolver: typeof jsonSchemaRefPlaceholderResolver; // @public @deprecated (undocumented) export class OpenApiRefProcessor implements CatalogProcessor { @@ -38,7 +38,7 @@ export class OpenApiRefProcessor implements CatalogProcessor { } // @public (undocumented) -export function refPlaceholderResolver( +export function jsonSchemaRefPlaceholderResolver( params: PlaceholderResolverParams, ): Promise; diff --git a/plugins/catalog-backend-module-openapi/src/index.ts b/plugins/catalog-backend-module-openapi/src/index.ts index 57f3d8806f..170c925a7f 100644 --- a/plugins/catalog-backend-module-openapi/src/index.ts +++ b/plugins/catalog-backend-module-openapi/src/index.ts @@ -13,12 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { refPlaceholderResolver } from './refPlaceholderResolver'; +import { jsonSchemaRefPlaceholderResolver } from './jsonSchemaRefPlaceholderResolver'; export { OpenApiRefProcessor } from './OpenApiRefProcessor'; -export { refPlaceholderResolver } from './refPlaceholderResolver'; +export { jsonSchemaRefPlaceholderResolver } from './jsonSchemaRefPlaceholderResolver'; /** * @public - * @deprecated replaced by refPlaceholderResolver + * @deprecated replaced by jsonSchemaRefPlaceholderResolver */ -export const openApiPlaceholderResolver = refPlaceholderResolver; +export const openApiPlaceholderResolver = jsonSchemaRefPlaceholderResolver; diff --git a/plugins/catalog-backend-module-openapi/src/refPlaceholderResolver.test.ts b/plugins/catalog-backend-module-openapi/src/jsonSchemaRefPlaceholderResolver.test.ts similarity index 86% rename from plugins/catalog-backend-module-openapi/src/refPlaceholderResolver.test.ts rename to plugins/catalog-backend-module-openapi/src/jsonSchemaRefPlaceholderResolver.test.ts index 9ecf0a2995..6aecc9b468 100644 --- a/plugins/catalog-backend-module-openapi/src/refPlaceholderResolver.test.ts +++ b/plugins/catalog-backend-module-openapi/src/jsonSchemaRefPlaceholderResolver.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ import { PlaceholderResolverParams } from '@backstage/plugin-catalog-backend'; -import { refPlaceholderResolver } from './refPlaceholderResolver'; +import { jsonSchemaRefPlaceholderResolver } from './jsonSchemaRefPlaceholderResolver'; import { bundleFileWithRefs } from './lib'; jest.mock('./lib', () => ({ @@ -23,7 +23,7 @@ jest.mock('./lib', () => ({ const bundled = ''; -describe('refPlaceholderResolver', () => { +describe('jsonSchemaRefPlaceholderResolver', () => { const mockResolveUrl = jest.fn(); mockResolveUrl.mockReturnValue('mockUrl'); @@ -50,13 +50,13 @@ describe('refPlaceholderResolver', () => { it('should throw error if unable to bundle the OpenAPI specification', async () => { (bundleFileWithRefs as any).mockRejectedValue(new Error('TEST')); - await expect(refPlaceholderResolver(params)).rejects.toThrow( + await expect(jsonSchemaRefPlaceholderResolver(params)).rejects.toThrow( 'Placeholder $openapi unable to bundle OpenAPI specification', ); }); it('should bundle the OpenAPI specification', async () => { - const result = await refPlaceholderResolver(params); + const result = await jsonSchemaRefPlaceholderResolver(params); expect(result).toEqual(bundled); }); diff --git a/plugins/catalog-backend-module-openapi/src/refPlaceholderResolver.ts b/plugins/catalog-backend-module-openapi/src/jsonSchemaRefPlaceholderResolver.ts similarity index 94% rename from plugins/catalog-backend-module-openapi/src/refPlaceholderResolver.ts rename to plugins/catalog-backend-module-openapi/src/jsonSchemaRefPlaceholderResolver.ts index 39c2e639ab..befafbde8a 100644 --- a/plugins/catalog-backend-module-openapi/src/refPlaceholderResolver.ts +++ b/plugins/catalog-backend-module-openapi/src/jsonSchemaRefPlaceholderResolver.ts @@ -19,7 +19,7 @@ import { processingResult } from '@backstage/plugin-catalog-node'; import { bundleFileWithRefs } from './lib'; /** @public */ -export async function refPlaceholderResolver( +export async function jsonSchemaRefPlaceholderResolver( params: PlaceholderResolverParams, ): Promise { const { content, url } = await readTextLocation(params); @@ -35,7 +35,7 @@ export async function refPlaceholderResolver( ); } catch (error) { throw new Error( - `Placeholder \$${params.key} unable to bundle OpenAPI specification at ${params.value}, ${error}`, + `Placeholder \$${params.key} unable to bundle the file at ${params.value}, ${error}`, ); } } From f68a7059b594c1946d3641fdbaf6b45f640af0b1 Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 22 Nov 2022 10:11:52 +0100 Subject: [PATCH 35/83] fixed last of const-insigts components deprecations' Signed-off-by: Simon --- .../src/components/AlertInsights/AlertInsights.tsx | 3 ++- .../cost-insights/src/components/CostGrowth/CostGrowth.tsx | 2 +- .../components/CostInsightsLayout/CostInsightsLayout.tsx | 2 +- .../CostInsightsNavigation/CostInsightsNavigation.test.tsx | 3 ++- .../src/components/PeriodSelect/PeriodSelect.test.tsx | 3 ++- .../src/components/ProductInsights/ProductInsights.test.tsx | 2 +- .../src/components/ProductInsights/ProductInsights.tsx | 3 ++- .../ProductInsightsCard/ProductEntityDialog.test.tsx | 2 +- .../components/ProductInsightsCard/ProductEntityDialog.tsx | 2 +- .../components/ProductInsightsCard/ProductEntityTable.tsx | 6 +++++- .../ProductInsightsCard/ProductInsightsCard.test.tsx | 3 ++- .../components/ProductInsightsCard/ProductInsightsCard.tsx | 3 ++- .../ProductInsightsCard/ProductInsightsCardList.tsx | 3 ++- .../components/ProductInsightsCard/ProductInsightsChart.tsx | 3 ++- .../ProjectGrowthInstructionsPage.tsx | 3 +-- .../src/components/ProjectSelect/ProjectSelect.tsx | 2 +- 16 files changed, 28 insertions(+), 17 deletions(-) diff --git a/plugins/cost-insights/src/components/AlertInsights/AlertInsights.tsx b/plugins/cost-insights/src/components/AlertInsights/AlertInsights.tsx index 2daacda85e..e48ae2789d 100644 --- a/plugins/cost-insights/src/components/AlertInsights/AlertInsights.tsx +++ b/plugins/cost-insights/src/components/AlertInsights/AlertInsights.tsx @@ -30,7 +30,8 @@ import { MapLoadingToProps, } from '../../hooks'; import { DefaultLoadingAction } from '../../utils/loading'; -import { Alert, AlertOptions, AlertStatus, Maybe } from '../../types'; +import { Alert, AlertOptions, AlertStatus } from '../../types'; +import { Maybe } from '@backstage/plugin-cost-insights-common'; import { isStatusSnoozed, isStatusAccepted, diff --git a/plugins/cost-insights/src/components/CostGrowth/CostGrowth.tsx b/plugins/cost-insights/src/components/CostGrowth/CostGrowth.tsx index ffc548c7ad..d0a4e7901a 100644 --- a/plugins/cost-insights/src/components/CostGrowth/CostGrowth.tsx +++ b/plugins/cost-insights/src/components/CostGrowth/CostGrowth.tsx @@ -17,12 +17,12 @@ import React from 'react'; import classnames from 'classnames'; import { - ChangeStatistic, CurrencyType, Duration, EngineerThreshold, GrowthType, } from '../../types'; +import { ChangeStatistic } from '@backstage/plugin-cost-insights-common'; import { rateOf } from '../../utils/currency'; import { growthOf } from '../../utils/change'; import { useCostGrowthStyles as useStyles } from '../../utils/styles'; diff --git a/plugins/cost-insights/src/components/CostInsightsLayout/CostInsightsLayout.tsx b/plugins/cost-insights/src/components/CostInsightsLayout/CostInsightsLayout.tsx index 93614bd64f..0a583aae0d 100644 --- a/plugins/cost-insights/src/components/CostInsightsLayout/CostInsightsLayout.tsx +++ b/plugins/cost-insights/src/components/CostInsightsLayout/CostInsightsLayout.tsx @@ -15,7 +15,7 @@ */ import React, { PropsWithChildren } from 'react'; import { makeStyles } from '@material-ui/core'; -import { Group } from '../../types'; +import { Group } from '@backstage/plugin-cost-insights-common'; import { CostInsightsTabs } from '../CostInsightsTabs'; import { Header, Page } from '@backstage/core-components'; diff --git a/plugins/cost-insights/src/components/CostInsightsNavigation/CostInsightsNavigation.test.tsx b/plugins/cost-insights/src/components/CostInsightsNavigation/CostInsightsNavigation.test.tsx index 8ccca96e0f..4cfabc119c 100644 --- a/plugins/cost-insights/src/components/CostInsightsNavigation/CostInsightsNavigation.test.tsx +++ b/plugins/cost-insights/src/components/CostInsightsNavigation/CostInsightsNavigation.test.tsx @@ -18,7 +18,8 @@ import React from 'react'; import { default as HappyFace } from '@material-ui/icons/SentimentSatisfiedAlt'; import { renderInTestApp } from '@backstage/test-utils'; import { CostInsightsNavigation } from './CostInsightsNavigation'; -import { Product, Icon } from '../../types'; +import { Icon } from '../../types'; +import { Product } from '@backstage/plugin-cost-insights-common'; import { MockConfigProvider, MockScrollProvider } from '../../testUtils'; import { getDefaultNavigationItems } from '../../utils/navigation'; diff --git a/plugins/cost-insights/src/components/PeriodSelect/PeriodSelect.test.tsx b/plugins/cost-insights/src/components/PeriodSelect/PeriodSelect.test.tsx index dfac13dd42..b7a1e034da 100644 --- a/plugins/cost-insights/src/components/PeriodSelect/PeriodSelect.test.tsx +++ b/plugins/cost-insights/src/components/PeriodSelect/PeriodSelect.test.tsx @@ -21,7 +21,8 @@ import userEvent from '@testing-library/user-event'; import { PeriodSelect, getDefaultOptions } from './PeriodSelect'; import { getDefaultPageFilters } from '../../utils/filters'; import { MockBillingDateProvider } from '../../testUtils'; -import { Group, Duration } from '../../types'; +import { Duration } from '../../types'; +import { Group } from '@backstage/plugin-cost-insights-common'; const DefaultPageFilters = getDefaultPageFilters([{ id: 'tools' }] as Group[]); const lastCompleteBillingDate = '2020-05-01'; diff --git a/plugins/cost-insights/src/components/ProductInsights/ProductInsights.test.tsx b/plugins/cost-insights/src/components/ProductInsights/ProductInsights.test.tsx index 128c9d50b9..3c6b731ce8 100644 --- a/plugins/cost-insights/src/components/ProductInsights/ProductInsights.test.tsx +++ b/plugins/cost-insights/src/components/ProductInsights/ProductInsights.test.tsx @@ -27,7 +27,7 @@ import { MockScrollProvider, MockLoadingProvider, } from '../../testUtils'; -import { Entity, Product } from '../../types'; +import { Entity, Product } from '@backstage/plugin-cost-insights-common'; // suppress recharts componentDidUpdate warnings jest.spyOn(console, 'warn').mockImplementation(() => {}); diff --git a/plugins/cost-insights/src/components/ProductInsights/ProductInsights.tsx b/plugins/cost-insights/src/components/ProductInsights/ProductInsights.tsx index 3eba868843..9df763a5d4 100644 --- a/plugins/cost-insights/src/components/ProductInsights/ProductInsights.tsx +++ b/plugins/cost-insights/src/components/ProductInsights/ProductInsights.tsx @@ -19,7 +19,8 @@ import { Box, Typography } from '@material-ui/core'; import { default as Alert } from '@material-ui/lab/Alert'; import { costInsightsApiRef } from '../../api'; import { ProductInsightsCardList } from '../ProductInsightsCard/ProductInsightsCardList'; -import { Duration, Entity, Maybe, Product } from '../../types'; +import { Duration } from '../../types'; +import { Entity, Maybe, Product } from '@backstage/plugin-cost-insights-common'; import { intervalsOf, DEFAULT_DURATION } from '../../utils/duration'; import { DefaultLoadingAction, diff --git a/plugins/cost-insights/src/components/ProductInsightsCard/ProductEntityDialog.test.tsx b/plugins/cost-insights/src/components/ProductInsightsCard/ProductEntityDialog.test.tsx index d3d12abe74..b0c35da493 100644 --- a/plugins/cost-insights/src/components/ProductInsightsCard/ProductEntityDialog.test.tsx +++ b/plugins/cost-insights/src/components/ProductInsightsCard/ProductEntityDialog.test.tsx @@ -18,7 +18,7 @@ import React from 'react'; import { wrapInTestApp } from '@backstage/test-utils'; import { ProductEntityDialog } from './ProductEntityDialog'; import { render } from '@testing-library/react'; -import { Entity } from '../../types'; +import { Entity } from '@backstage/plugin-cost-insights-common'; const atomicEntity: Entity = { id: null, diff --git a/plugins/cost-insights/src/components/ProductInsightsCard/ProductEntityDialog.tsx b/plugins/cost-insights/src/components/ProductInsightsCard/ProductEntityDialog.tsx index 50b2ff993c..55fa795728 100644 --- a/plugins/cost-insights/src/components/ProductInsightsCard/ProductEntityDialog.tsx +++ b/plugins/cost-insights/src/components/ProductInsightsCard/ProductEntityDialog.tsx @@ -18,7 +18,7 @@ import React, { useState } from 'react'; import { Dialog, IconButton } from '@material-ui/core'; import { default as CloseButton } from '@material-ui/icons/Close'; import { useEntityDialogStyles as useStyles } from '../../utils/styles'; -import { Entity } from '../../types'; +import { Entity } from '@backstage/plugin-cost-insights-common'; import { ProductEntityTable, ProductEntityTableOptions, diff --git a/plugins/cost-insights/src/components/ProductInsightsCard/ProductEntityTable.tsx b/plugins/cost-insights/src/components/ProductInsightsCard/ProductEntityTable.tsx index 95ba4f2f2d..24115e830a 100644 --- a/plugins/cost-insights/src/components/ProductInsightsCard/ProductEntityTable.tsx +++ b/plugins/cost-insights/src/components/ProductInsightsCard/ProductEntityTable.tsx @@ -20,7 +20,11 @@ import { Typography } from '@material-ui/core'; import { costFormatter, formatChange } from '../../utils/formatters'; import { useEntityDialogStyles as useStyles } from '../../utils/styles'; import { CostGrowthIndicator } from '../CostGrowth'; -import { BarChartOptions, ChangeStatistic, Entity } from '../../types'; +import { BarChartOptions } from '../../types'; +import { + ChangeStatistic, + Entity, +} from '@backstage/plugin-cost-insights-common'; import { Table, TableColumn } from '@backstage/core-components'; export type ProductEntityTableOptions = Partial< diff --git a/plugins/cost-insights/src/components/ProductInsightsCard/ProductInsightsCard.test.tsx b/plugins/cost-insights/src/components/ProductInsightsCard/ProductInsightsCard.test.tsx index 737019e77a..b24b3bd366 100644 --- a/plugins/cost-insights/src/components/ProductInsightsCard/ProductInsightsCard.test.tsx +++ b/plugins/cost-insights/src/components/ProductInsightsCard/ProductInsightsCard.test.tsx @@ -28,7 +28,8 @@ import { MockScrollProvider, MockLoadingProvider, } from '../../testUtils'; -import { Duration, Entity, Product } from '../../types'; +import { Duration } from '../../types'; +import { Entity, Product } from '@backstage/plugin-cost-insights-common'; // suppress recharts componentDidUpdate warnings jest.spyOn(console, 'warn').mockImplementation(() => {}); diff --git a/plugins/cost-insights/src/components/ProductInsightsCard/ProductInsightsCard.tsx b/plugins/cost-insights/src/components/ProductInsightsCard/ProductInsightsCard.tsx index 2b4ee4b0db..a587bfb26e 100644 --- a/plugins/cost-insights/src/components/ProductInsightsCard/ProductInsightsCard.tsx +++ b/plugins/cost-insights/src/components/ProductInsightsCard/ProductInsightsCard.tsx @@ -28,7 +28,8 @@ import { PeriodSelect } from '../PeriodSelect'; import { ProductInsightsChart } from './ProductInsightsChart'; import { useProductInsightsCardStyles as useStyles } from '../../utils/styles'; import { DefaultLoadingAction } from '../../utils/loading'; -import { Duration, Entity, Maybe, Product } from '../../types'; +import { Duration } from '../../types'; +import { Entity, Maybe, Product } from '@backstage/plugin-cost-insights-common'; import { MapLoadingToProps, useLastCompleteBillingDate, diff --git a/plugins/cost-insights/src/components/ProductInsightsCard/ProductInsightsCardList.tsx b/plugins/cost-insights/src/components/ProductInsightsCard/ProductInsightsCardList.tsx index ecf60b4bef..3ae97daecb 100644 --- a/plugins/cost-insights/src/components/ProductInsightsCard/ProductInsightsCardList.tsx +++ b/plugins/cost-insights/src/components/ProductInsightsCard/ProductInsightsCardList.tsx @@ -17,7 +17,8 @@ import React from 'react'; import { Box, CircularProgress, Collapse } from '@material-ui/core'; import { ProductInsightsCard } from './ProductInsightsCard'; -import { Duration, Entity, Product } from '../../types'; +import { Duration } from '../../types'; +import { Entity, Product } from '@backstage/plugin-cost-insights-common'; import { ProductState } from '../../utils/loading'; type ProductInsightsCardListProps = { diff --git a/plugins/cost-insights/src/components/ProductInsightsCard/ProductInsightsChart.tsx b/plugins/cost-insights/src/components/ProductInsightsCard/ProductInsightsChart.tsx index b77b415e1e..751a37f67e 100644 --- a/plugins/cost-insights/src/components/ProductInsightsCard/ProductInsightsChart.tsx +++ b/plugins/cost-insights/src/components/ProductInsightsCard/ProductInsightsChart.tsx @@ -48,7 +48,8 @@ import { useProductInsightsChartStyles as useStyles, useBarChartLayoutStyles as useLayoutStyles, } from '../../utils/styles'; -import { Duration, Entity, Maybe } from '../../types'; +import { Duration } from '../../types'; +import { Entity, Maybe } from '@backstage/plugin-cost-insights-common'; import { choose } from '../../utils/change'; import { TooltipRenderer } from '../../types/Tooltip'; diff --git a/plugins/cost-insights/src/components/ProjectGrowthInstructionsPage/ProjectGrowthInstructionsPage.tsx b/plugins/cost-insights/src/components/ProjectGrowthInstructionsPage/ProjectGrowthInstructionsPage.tsx index 35b00ce6f6..0435210a98 100644 --- a/plugins/cost-insights/src/components/ProjectGrowthInstructionsPage/ProjectGrowthInstructionsPage.tsx +++ b/plugins/cost-insights/src/components/ProjectGrowthInstructionsPage/ProjectGrowthInstructionsPage.tsx @@ -23,10 +23,9 @@ import { Alert, DEFAULT_DATE_FORMAT, Duration, - Entity, - Product, ProjectGrowthData, } from '../../types'; +import { Entity, Product } from '@backstage/plugin-cost-insights-common'; import { ProjectGrowthAlert } from '../../alerts'; import { InfoCard } from '@backstage/core-components'; diff --git a/plugins/cost-insights/src/components/ProjectSelect/ProjectSelect.tsx b/plugins/cost-insights/src/components/ProjectSelect/ProjectSelect.tsx index d46123b001..c83fa67d94 100644 --- a/plugins/cost-insights/src/components/ProjectSelect/ProjectSelect.tsx +++ b/plugins/cost-insights/src/components/ProjectSelect/ProjectSelect.tsx @@ -15,7 +15,7 @@ */ import React from 'react'; import { MenuItem, Select } from '@material-ui/core'; -import { Maybe, Project } from '../../types'; +import { Maybe, Project } from '@backstage/plugin-cost-insights-common'; import { useSelectStyles as useStyles } from '../../utils/styles'; type ProjectSelectProps = { From 40e7e6e1a2ed0e3b0fb71557b7f2291a3a686d73 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 22 Nov 2022 09:43:28 +0000 Subject: [PATCH 36/83] Update dependency typescript-json-schema to ^0.55.0 Signed-off-by: Renovate Bot --- .changeset/renovate-a5f7839.md | 5 ++++ packages/config-loader/package.json | 2 +- yarn.lock | 40 +++++++++++++++++++++-------- 3 files changed, 36 insertions(+), 11 deletions(-) create mode 100644 .changeset/renovate-a5f7839.md diff --git a/.changeset/renovate-a5f7839.md b/.changeset/renovate-a5f7839.md new file mode 100644 index 0000000000..d1ab22e04a --- /dev/null +++ b/.changeset/renovate-a5f7839.md @@ -0,0 +1,5 @@ +--- +'@backstage/config-loader': patch +--- + +Updated dependency `typescript-json-schema` to `^0.55.0`. diff --git a/packages/config-loader/package.json b/packages/config-loader/package.json index 7c9306cb64..3d4e7b5c5b 100644 --- a/packages/config-loader/package.json +++ b/packages/config-loader/package.json @@ -45,7 +45,7 @@ "json-schema-merge-allof": "^0.8.1", "json-schema-traverse": "^1.0.0", "node-fetch": "^2.6.7", - "typescript-json-schema": "^0.54.0", + "typescript-json-schema": "^0.55.0", "yaml": "^2.0.0", "yup": "^0.32.9" }, diff --git a/yarn.lock b/yarn.lock index 2793196219..2a7b3de7b1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3298,7 +3298,7 @@ __metadata: mock-fs: ^5.1.0 msw: ^0.48.0 node-fetch: ^2.6.7 - typescript-json-schema: ^0.54.0 + typescript-json-schema: ^0.55.0 yaml: ^2.0.0 yup: ^0.32.9 languageName: unknown @@ -35662,7 +35662,7 @@ __metadata: languageName: node linkType: hard -"ts-node@npm:^10.0.0, ts-node@npm:^10.2.1, ts-node@npm:^10.4.0, ts-node@npm:^10.8.1": +"ts-node@npm:^10.0.0, ts-node@npm:^10.4.0, ts-node@npm:^10.8.1, ts-node@npm:^10.9.1": version: 10.9.1 resolution: "ts-node@npm:10.9.1" dependencies: @@ -35900,25 +35900,25 @@ __metadata: languageName: node linkType: hard -"typescript-json-schema@npm:^0.54.0": - version: 0.54.0 - resolution: "typescript-json-schema@npm:0.54.0" +"typescript-json-schema@npm:^0.55.0": + version: 0.55.0 + resolution: "typescript-json-schema@npm:0.55.0" dependencies: "@types/json-schema": ^7.0.9 "@types/node": ^16.9.2 glob: ^7.1.7 path-equal: ^1.1.2 safe-stable-stringify: ^2.2.0 - ts-node: ^10.2.1 - typescript: ~4.6.0 + ts-node: ^10.9.1 + typescript: ~4.8.2 yargs: ^17.1.1 bin: typescript-json-schema: bin/typescript-json-schema - checksum: 49e03bd2612f79fe3ee9e9afcea34ae563da9aa799a8b4cf12b73feb60eb62a0786300eedb30261c69c482ed7e545acf1e5617d59861e6deee4f6570a658de88 + checksum: 4188e9d4cc1f1fc3201e2aa06b8d87d35695b0eaf049ff9d2cd3027d87406efc6978c4f90c2bf06f4fcd8d6dd40ceb65e744dc3cf9b412e1f74b8eb5bae96a05 languageName: node linkType: hard -"typescript@npm:~4.6.0, typescript@npm:~4.6.3": +"typescript@npm:~4.6.3": version: 4.6.4 resolution: "typescript@npm:4.6.4" bin: @@ -35938,7 +35938,17 @@ __metadata: languageName: node linkType: hard -"typescript@patch:typescript@~4.6.0#~builtin, typescript@patch:typescript@~4.6.3#~builtin": +"typescript@npm:~4.8.2": + version: 4.8.4 + resolution: "typescript@npm:4.8.4" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 3e4f061658e0c8f36c820802fa809e0fd812b85687a9a2f5430bc3d0368e37d1c9605c3ce9b39df9a05af2ece67b1d844f9f6ea8ff42819f13bcb80f85629af0 + languageName: node + linkType: hard + +"typescript@patch:typescript@~4.6.3#~builtin": version: 4.6.4 resolution: "typescript@patch:typescript@npm%3A4.6.4#~builtin::version=4.6.4&hash=a1c5e5" bin: @@ -35958,6 +35968,16 @@ __metadata: languageName: node linkType: hard +"typescript@patch:typescript@~4.8.2#~builtin": + version: 4.8.4 + resolution: "typescript@patch:typescript@npm%3A4.8.4#~builtin::version=4.8.4&hash=a1c5e5" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 563a0ef47abae6df27a9a3ab38f75fc681f633ccf1a3502b1108e252e187787893de689220f4544aaf95a371a4eb3141e4a337deb9895de5ac3c1ca76430e5f0 + languageName: node + linkType: hard + "ua-parser-js@npm:^0.7.18": version: 0.7.28 resolution: "ua-parser-js@npm:0.7.28" From d379b6f070a104f454d0ca9d78a1029345d68cd8 Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 22 Nov 2022 10:54:25 +0100 Subject: [PATCH 37/83] added changeset and api report Signed-off-by: Simon --- .changeset/hip-chairs-tap.md | 5 +++++ plugins/cost-insights/api-report.md | 29 +++++++++++++++++------------ 2 files changed, 22 insertions(+), 12 deletions(-) create mode 100644 .changeset/hip-chairs-tap.md diff --git a/.changeset/hip-chairs-tap.md b/.changeset/hip-chairs-tap.md new file mode 100644 index 0000000000..8eca0a9292 --- /dev/null +++ b/.changeset/hip-chairs-tap.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-cost-insights': patch +--- + +Internal refactor to avoid usage of deprecated symbols diff --git a/plugins/cost-insights/api-report.md b/plugins/cost-insights/api-report.md index dd4e404450..ba93878aea 100644 --- a/plugins/cost-insights/api-report.md +++ b/plugins/cost-insights/api-report.md @@ -11,10 +11,15 @@ import { BackstagePlugin } from '@backstage/core-plugin-api'; import { BackstageTheme } from '@backstage/theme'; import { ChangeStatistic as ChangeStatistic_2 } from '@backstage/plugin-cost-insights-common'; import * as common from '@backstage/plugin-cost-insights-common'; +import { Cost as Cost_2 } from '@backstage/plugin-cost-insights-common'; import { Dispatch } from 'react'; +import { Entity as Entity_2 } from '@backstage/plugin-cost-insights-common'; import { ForwardRefExoticComponent } from 'react'; +import { Group as Group_2 } from '@backstage/plugin-cost-insights-common'; import { Maybe as Maybe_2 } from '@backstage/plugin-cost-insights-common'; +import { MetricData as MetricData_2 } from '@backstage/plugin-cost-insights-common'; import { PaletteOptions } from '@material-ui/core/styles/createPalette'; +import { Project as Project_2 } from '@backstage/plugin-cost-insights-common'; import { PropsWithChildren } from 'react'; import { ReactNode } from 'react'; import { RefAttributes } from 'react'; @@ -247,34 +252,34 @@ export const CostGrowthIndicator: ( // @public (undocumented) export type CostGrowthIndicatorProps = TypographyProps & { - change: ChangeStatistic; + change: ChangeStatistic_2; formatter?: ( - change: ChangeStatistic, + change: ChangeStatistic_2, options?: { absolute: boolean; }, - ) => Maybe; + ) => Maybe_2; }; // @public (undocumented) export type CostGrowthProps = { - change: ChangeStatistic; + change: ChangeStatistic_2; duration: Duration; }; // @public (undocumented) export type CostInsightsApi = { getLastCompleteBillingDate(): Promise; - getUserGroups(userId: string): Promise; - getGroupProjects(group: string): Promise; + getUserGroups(userId: string): Promise; + getGroupProjects(group: string): Promise; getCatalogEntityDailyCost?( catalogEntityRef: string, intervals: string, - ): Promise; - getGroupDailyCost(group: string, intervals: string): Promise; - getProjectDailyCost(project: string, intervals: string): Promise; - getDailyMetricData(metric: string, intervals: string): Promise; - getProductInsights(options: ProductInsightsOptions): Promise; + ): Promise; + getGroupDailyCost(group: string, intervals: string): Promise; + getProjectDailyCost(project: string, intervals: string): Promise; + getDailyMetricData(metric: string, intervals: string): Promise; + getProductInsights(options: ProductInsightsOptions): Promise; getAlerts(group: string): Promise; }; @@ -538,7 +543,7 @@ export type ProductInsightsOptions = { product: string; group: string; intervals: string; - project: Maybe; + project: Maybe_2; }; // @public (undocumented) From 624162ad3a5efbd47f05e6867c632f606fa2900f Mon Sep 17 00:00:00 2001 From: skgandikota Date: Tue, 22 Nov 2022 16:23:35 +0530 Subject: [PATCH 38/83] rephrased changeset to Use from when creating new Documentation Feedback issue. is the default value. Co-authored-by: kcheriyath Co-authored-by: aswathysen Signed-off-by: skgandikota --- .changeset/tender-parrots-cover.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/tender-parrots-cover.md b/.changeset/tender-parrots-cover.md index 433d030628..5272fcbdce 100644 --- a/.changeset/tender-parrots-cover.md +++ b/.changeset/tender-parrots-cover.md @@ -2,4 +2,4 @@ '@backstage/plugin-techdocs-module-addons-contrib': patch --- -Refactored Report issue body in the tech-doc addons by getting the app title from `appconfig.yml` using `configApiRef`, In case `appTitle` not mentioned app Tile `new const` will default to `Backstage` +Use `app.title` from `app-config.yaml` when creating new Documentation Feedback issue. `Backstage` is the default value. From 39dd063fcbf5d53a7ed6e67888bd51c6c9206db2 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 22 Nov 2022 13:24:07 +0100 Subject: [PATCH 39/83] docs/deployment: note that separate frontend is optional Signed-off-by: Patrik Oldsberg --- docs/deployment/docker.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/deployment/docker.md b/docs/deployment/docker.md index 30276a97ab..88c22afb9b 100644 --- a/docs/deployment/docker.md +++ b/docs/deployment/docker.md @@ -275,6 +275,11 @@ browser at `http://localhost:7007` ## Separate Frontend +> NOTE: This is an optional step, and you will lose out on the features of the +> `@backstage/plugin-app-backend` plugin. Most notably the frontend configuration +> will no longer be injected by the backend, you will instead need to use the +> correct configuration when building the frontend bundle. + It is sometimes desirable to serve the frontend separately from the backend, either from a separate image or for example a static file serving provider. The first step in doing so is to remove the `app-backend` plugin from the backend From b5851797705f31d9d1343195839b4841a19ea2d2 Mon Sep 17 00:00:00 2001 From: Liam Rathke Date: Thu, 11 Aug 2022 15:48:18 -0700 Subject: [PATCH 40/83] feat: Liam Rathke pre RFC update commit squash Signed-off-by: Liam Rathke Copy of proxy plugin work Signed-off-by: Liam Rathke Adds B64 encoding, TLS verify check Signed-off-by: Liam Rathke Sets up test scaffolding Signed-off-by: Liam Rathke Finishes proxy implementation tests Signed-off-by: Liam Rathke Removes deprecated buffer method Signed-off-by: Liam Rathke Adds additional HTTP verbs Signed-off-by: Liam Rathke Removes fallback Signed-off-by: Liam Rathke Adds some content-agnosticness, removes nitpick Signed-off-by: Liam Rathke Adds changeset Signed-off-by: Liam Rathke Fixes TSC errors? Signed-off-by: Liam Rathke Adds API Report docs Signed-off-by: Liam Rathke Removes unnecessary KubernetesRequestAuth parameter Signed-off-by: Liam Rathke Somehow adds new docs??? Signed-off-by: Liam Rathke Fixes some code inline with review comments Signed-off-by: Liam Rathke Updates API report Signed-off-by: Liam Rathke Fixes tests Signed-off-by: Liam Rathke --- .changeset/rich-garlics-play.md | 6 + plugins/kubernetes-backend/api-report.md | 13 + plugins/kubernetes-backend/package.json | 1 + .../src/service/KubernetesBuilder.ts | 39 +- .../src/service/KubernetesProxy.test.ts | 342 ++++++++++++++++++ .../src/service/KubernetesProxy.ts | 286 +++++++++++++++ plugins/kubernetes-backend/src/types/types.ts | 8 + plugins/kubernetes-common/api-report.md | 10 + plugins/kubernetes-common/src/types.ts | 4 + 9 files changed, 708 insertions(+), 1 deletion(-) create mode 100644 .changeset/rich-garlics-play.md create mode 100644 plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts create mode 100644 plugins/kubernetes-backend/src/service/KubernetesProxy.ts diff --git a/.changeset/rich-garlics-play.md b/.changeset/rich-garlics-play.md new file mode 100644 index 0000000000..5589a70e35 --- /dev/null +++ b/.changeset/rich-garlics-play.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-kubernetes-backend': patch +'@backstage/plugin-kubernetes-common': patch +--- + +Added Kubernetes proxy API route to backend Kubernetes plugin, allowing Backstage plugin developers to read/write new information from Kubernetes (if proper credentials are provided). diff --git a/plugins/kubernetes-backend/api-report.md b/plugins/kubernetes-backend/api-report.md index d51ec4c211..303aaa3017 100644 --- a/plugins/kubernetes-backend/api-report.md +++ b/plugins/kubernetes-backend/api-report.md @@ -209,8 +209,15 @@ export class KubernetesBuilder { // (undocumented) protected getObjectTypesToFetch(): ObjectToFetch[] | undefined; // (undocumented) + protected getProxyServices(): KubernetesProxyServices; + // (undocumented) protected getServiceLocatorMethod(): ServiceLocatorMethod; // (undocumented) + protected makeProxyRequest( + req: express.Request, + res: express.Response, + ): Promise; + // (undocumented) setClusterSupplier(clusterSupplier?: KubernetesClustersSupplier): this; // (undocumented) setDefaultClusterRefreshInterval(refreshInterval: Duration): this; @@ -322,6 +329,12 @@ export type KubernetesObjectTypes = | 'statefulsets' | 'daemonsets'; +// @alpha (undocumented) +export interface KubernetesProxyServices { + // (undocumented) + kcs: KubernetesClustersSupplier; +} + // @alpha export interface KubernetesServiceLocator { // (undocumented) diff --git a/plugins/kubernetes-backend/package.json b/plugins/kubernetes-backend/package.json index acf28eeb36..95b3000069 100644 --- a/plugins/kubernetes-backend/package.json +++ b/plugins/kubernetes-backend/package.json @@ -56,6 +56,7 @@ "helmet": "^6.0.0", "lodash": "^4.17.21", "luxon": "^3.0.0", + "node-fetch": "^2.6.0", "morgan": "^1.10.0", "stream-buffers": "^3.0.2", "winston": "^3.2.1", diff --git a/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts b/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts index 304885f3e2..c7f569267e 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts @@ -30,8 +30,12 @@ import { KubernetesFetcher, KubernetesServiceLocator, KubernetesObjectsProviderOptions, + KubernetesProxyServices, } from '../types/types'; import { KubernetesClientProvider } from './KubernetesClientProvider'; + +import { KubernetesProxy, KubernetesProxyResponse } from './KubernetesProxy'; + import { DEFAULT_OBJECTS, KubernetesFanOutHandler, @@ -76,12 +80,15 @@ export class KubernetesBuilder { private objectsProvider?: KubernetesObjectsProvider; private fetcher?: KubernetesFetcher; private serviceLocator?: KubernetesServiceLocator; + private proxy: KubernetesProxy; static createBuilder(env: KubernetesEnvironment) { return new KubernetesBuilder(env); } - constructor(protected readonly env: KubernetesEnvironment) {} + constructor(protected readonly env: KubernetesEnvironment) { + this.proxy = new KubernetesProxy(env.logger); + } public async build(): KubernetesBuilderReturn { const logger = this.env.logger; @@ -273,6 +280,12 @@ export class KubernetesBuilder { }); }); + router.get('/proxy/:encodedQuery', this.makeProxyRequest.bind(this)); + router.post('/proxy/:encodedQuery', this.makeProxyRequest.bind(this)); + router.put('/proxy/:encodedQuery', this.makeProxyRequest.bind(this)); + router.patch('/proxy/:encodedQuery', this.makeProxyRequest.bind(this)); + router.delete('/proxy/:encodedQuery', this.makeProxyRequest.bind(this)); + addResourceRoutesToRouter(router, catalogApi, objectsProvider); return router; @@ -325,4 +338,28 @@ export class KubernetesBuilder { return objectTypesToFetch; } + + protected async makeProxyRequest( + req: express.Request, + res: express.Response, + ) { + const services = this.getProxyServices(); + const proxyResponse: KubernetesProxyResponse = + await this.proxy.handleProxyRequest(services, req); + res.status(proxyResponse.code).json(proxyResponse.data); + } + + protected getProxyServices(): KubernetesProxyServices { + const kcs = + this.clusterSupplier ?? + this.buildClusterSupplier(this.defaultClusterRefreshInterval); + + if (!kcs) { + this.env.logger.error('could not find cluster supplier!'); + } + + return { + kcs, + }; + } } diff --git a/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts b/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts new file mode 100644 index 0000000000..c692355fbb --- /dev/null +++ b/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts @@ -0,0 +1,342 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { getVoidLogger } from '@backstage/backend-common'; +import { + ClusterDetails, + KubernetesClustersSupplier, + KubernetesProxyServices, +} from '../types/types'; +import { KubernetesProxy } from './KubernetesProxy'; + +import { Request } from 'express'; + +import 'buffer'; + +jest.mock('node-fetch'); +const { Response } = jest.requireActual('node-fetch'); + +import fetch from 'node-fetch'; + +describe('KubernetesProxy', () => { + let _clientMock: any; + let sut: KubernetesProxy; + + const buildEncodedRequest = ( + clustersHeader: any, + query: string, + body?: any, + ): Request => { + const encodedQuery = encodeURIComponent(query); + const encodedClusters = Buffer.from( + JSON.stringify(clustersHeader), + ).toString('base64'); + + const req = { + params: { + encodedQuery, + }, + header: (key: string) => { + let value: string = ''; + switch (key) { + case 'Content-Type': { + value = 'application/json'; + break; + } + case 'X-Kubernetes-Clusters': { + value = encodedClusters; + break; + } + default: { + break; + } + } + return value; + }, + } as unknown as Request; + + if (body) { + req.body = body; + } + + return req; + }; + + const buildProxyServicesWithClusters = ( + clusters: ClusterDetails[], + ): KubernetesProxyServices => { + const kcs: KubernetesClustersSupplier = { + getClusters: async () => { + return clusters; + }, + }; + + return { + kcs, + }; + }; + + beforeEach(() => { + jest.resetAllMocks(); + _clientMock = { + handleProxyRequest: jest.fn(), + }; + + sut = new KubernetesProxy(getVoidLogger()); + }); + + it('should return a 404 if no clusters are found', async () => { + const services = buildProxyServicesWithClusters([]); + const req = buildEncodedRequest({}, 'api'); + + const result = await sut.handleProxyRequest(services, req); + + expect(result.code).toEqual(404); + expect(fetch).not.toHaveBeenCalled(); + }); + + it('should match the response code of the Kubernetes response (single cluster)', async () => { + const services = buildProxyServicesWithClusters([ + { + name: 'cluster1', + url: 'http://localhost:9999', + serviceAccountToken: 'token', + authProvider: 'serviceAccount', + skipTLSVerify: true, + }, + ]); + const req = buildEncodedRequest({ cluster1: 'token' }, 'api'); + + const apiResponse = { + kind: 'APIVersions', + versions: ['v1'], + serverAddressByClientCIDRs: [ + { + clientCIDR: '0.0.0.0/0', + serverAddress: '192.168.0.1:3333', + }, + ], + }; + + // @ts-ignore-next-line + (fetch as jest.MockedFunction).mockResolvedValue( + new Response(JSON.stringify(apiResponse), { + status: 299, + }), + ); + + const result = await sut.handleProxyRequest(services, req); + + expect(fetch).toBeCalledTimes(1); + expect(result.code).toEqual(299); + }); + + it('should match the response code of the best Kubernetes response (multi cluster)', async () => { + const services = buildProxyServicesWithClusters([ + { + name: 'cluster1', + url: 'http://localhost:9998', + serviceAccountToken: 'token', + authProvider: 'serviceAccount', + skipTLSVerify: true, + }, + { + name: 'cluster2', + url: 'http://localhost:9999', + serviceAccountToken: 'token', + authProvider: 'serviceAccount', + skipTLSVerify: true, + }, + ]); + const req = buildEncodedRequest( + { cluster1: 'token', cluster2: 'token' }, + 'api', + ); + + const apiResponse1 = { + kind: 'APIVersions', + versions: ['v1'], + serverAddressByClientCIDRs: [ + { + clientCIDR: '0.0.0.0/0', + serverAddress: '192.168.0.1:3333', + }, + ], + }; + + const apiResponse2 = { + kind: 'Status', + apiVersion: 'v1', + metadata: {}, + status: 'Failure', + message: 'Unauthorized', + reason: 'Unauthorized', + code: 401, + }; + + (fetch as jest.MockedFunction) + .mockResolvedValueOnce( + new Response(JSON.stringify(apiResponse1), { + status: 200, + }), + ) + .mockResolvedValueOnce( + new Response(JSON.stringify(apiResponse2), { + status: 401, + }), + ); + + const result = await sut.handleProxyRequest(services, req); + + expect(fetch).toBeCalledTimes(2); + expect(result.code).toEqual(200); + }); + + it('should pass the exact response data from Kubernetes (single cluster)', async () => { + const services = buildProxyServicesWithClusters([ + { + name: 'cluster1', + url: 'http://localhost:9999', + serviceAccountToken: 'token', + authProvider: 'serviceAccount', + skipTLSVerify: true, + }, + ]); + const req = buildEncodedRequest({ cluster1: 'token' }, 'api'); + + const apiResponse = { + kind: 'APIVersions', + versions: ['v1'], + serverAddressByClientCIDRs: [ + { + clientCIDR: '0.0.0.0/0', + serverAddress: '192.168.0.1:3333', + }, + ], + }; + + // @ts-ignore-next-line + (fetch as jest.MockedFunction).mockResolvedValue( + new Response(JSON.stringify(apiResponse), { + status: 200, + }), + ); + + const result = await sut.handleProxyRequest(services, req); + + const resultString = JSON.stringify(result.data); + const expectedString = JSON.stringify({ + cluster1: { + kind: 'APIVersions', + versions: ['v1'], + serverAddressByClientCIDRs: [ + { + clientCIDR: '0.0.0.0/0', + serverAddress: '192.168.0.1:3333', + }, + ], + }, + }); + + expect(fetch).toBeCalledTimes(1); + expect(resultString).toEqual(expectedString); + }); + + it('should pass the exact response data from Kubernetes (multi cluster)', async () => { + const services = buildProxyServicesWithClusters([ + { + name: 'cluster1', + url: 'http://localhost:9998', + serviceAccountToken: 'token', + authProvider: 'serviceAccount', + skipTLSVerify: true, + }, + { + name: 'cluster2', + url: 'http://localhost:9999', + serviceAccountToken: 'token', + authProvider: 'serviceAccount', + skipTLSVerify: true, + }, + ]); + const req = buildEncodedRequest( + { cluster1: 'token', cluster2: 'token' }, + 'api', + ); + + const apiResponse1 = { + kind: 'APIVersions', + versions: ['v1'], + serverAddressByClientCIDRs: [ + { + clientCIDR: '0.0.0.0/0', + serverAddress: '192.168.0.1:3333', + }, + ], + }; + + const apiResponse2 = { + kind: 'Status', + apiVersion: 'v1', + metadata: {}, + status: 'Failure', + message: 'Unauthorized', + reason: 'Unauthorized', + code: 401, + }; + + // @ts-ignore-next-line + (fetch as jest.MockedFunction) + .mockResolvedValueOnce( + new Response(JSON.stringify(apiResponse1), { + status: 200, + }), + ) + .mockResolvedValueOnce( + new Response(JSON.stringify(apiResponse2), { + status: 401, + }), + ); + + const result = await sut.handleProxyRequest(services, req); + + const resultString = JSON.stringify(result.data); + const expectedString = JSON.stringify({ + cluster1: { + kind: 'APIVersions', + versions: ['v1'], + serverAddressByClientCIDRs: [ + { + clientCIDR: '0.0.0.0/0', + serverAddress: '192.168.0.1:3333', + }, + ], + }, + cluster2: { + kind: 'Status', + apiVersion: 'v1', + metadata: {}, + status: 'Failure', + message: 'Unauthorized', + reason: 'Unauthorized', + code: 401, + }, + }); + + expect(fetch).toBeCalledTimes(2); + expect(resultString).toEqual(expectedString); + }); +}); diff --git a/plugins/kubernetes-backend/src/service/KubernetesProxy.ts b/plugins/kubernetes-backend/src/service/KubernetesProxy.ts new file mode 100644 index 0000000000..e073ab3ec1 --- /dev/null +++ b/plugins/kubernetes-backend/src/service/KubernetesProxy.ts @@ -0,0 +1,286 @@ +/* + * 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 { KubeConfig, bufferFromFileOrString } from '@kubernetes/client-node'; +import { Logger } from 'winston'; +import fetch from 'node-fetch'; +import * as https from 'https'; + +import type { Request } from 'express'; + +import { + ClusterDetails, + KubernetesProxyServices, + KubernetesClustersSupplier, +} from '../types/types'; + +const HEADER_CONTENT_TYPE: string = 'Content-Type'; +const APPLICATION_JSON: string = 'application/json'; + +const HEADER_KUBERNETES_CLUSTERS: string = 'X-Kubernetes-Clusters'; + +const ERROR_BAD_REQUEST: number = 400; +const ERROR_NOT_FOUND: number = 404; +const ERROR_INTERNAL_SERVER: number = 500; + +const CLUSTER_USER_NAME: string = 'backstage'; + +export interface KubernetesProxyResponse { + code: number; + data: any; + cluster?: string; +} + +interface KubernetesProxyClusters { + [key: string]: string; +} + +export class KubernetesProxy { + constructor(protected readonly logger: Logger) {} + + public async handleProxyRequest( + services: KubernetesProxyServices, + req: Request, + ): Promise { + const krc = this.getKubernetesRequestedClusters(req); + + if (Object.keys(krc).length < 1) { + return { + code: ERROR_NOT_FOUND, + data: 'No clusters found!', + }; + } + + const details = await this.getClusterDetails(services.kcs, krc); + + if (details.length < 1) { + return { + code: ERROR_NOT_FOUND, + data: 'No clusters found!', + }; + } + + const responses = await Promise.all( + details.map(async d => { + const response = await this.makeRequestToCluster(d, req); + return response; + }), + ); + + const data: { [key: string]: any } = {}; + const codes: number[] = []; + + responses.forEach(kpr => { + if (kpr.cluster) { + data[kpr.cluster] = kpr.data; + codes.push(kpr.code); + } + }); + + const code = this.getBestResponseCode(codes); + + const res: KubernetesProxyResponse = { + code, + data, + }; + + return res; + } + + private getKubernetesRequestedClusters( + req: Request, + ): KubernetesProxyClusters { + const encodedClusters: string = + req.header(HEADER_KUBERNETES_CLUSTERS) ?? ''; + + if (!encodedClusters) { + return {}; + } + + try { + const decodedClusters = Buffer.from(encodedClusters, 'base64').toString(); + const clusters: KubernetesProxyClusters = JSON.parse(decodedClusters); + return clusters; + } catch (e: any) { + this.logger.debug( + `error with encoded cluster header: ${JSON.stringify(e)}`, + ); + } + return {}; + } + + private async getClusterDetails( + clusterSupplier: KubernetesClustersSupplier, + krc: KubernetesProxyClusters, + ): Promise { + const clusters = await clusterSupplier.getClusters(); + + const clusterNames = Object.keys(krc); + + const clusterDetails = clusters.filter(c => clusterNames.includes(c.name)); + + const clusterDetailsAuth = clusterDetails.map(c => { + const cAuth: ClusterDetails = Object.assign(c, { + serviceAccountToken: krc[c.name], + }); + return cAuth; + }); + + return clusterDetailsAuth; + } + + private getClusterURI(details: ClusterDetails): string { + const client = this.getKubeConfig(details); + return client.getCurrentCluster()?.server || ''; + } + + private async makeRequestToCluster( + details: ClusterDetails, + req: Request, + ): Promise { + const serverIP = this.getClusterURI(details); + if (!serverIP) { + return { + code: ERROR_INTERNAL_SERVER, + data: null, + }; + } + + const query = decodeURIComponent(req.params.encodedQuery) || ''; + const uri = `${serverIP}/${query}`; + + const contentType = req.header(HEADER_CONTENT_TYPE) || APPLICATION_JSON; + + const res = await this.sendClusterRequest( + details, + uri, + req.method, + contentType, + req.body, + ); + + return res; + } + + private async sendClusterRequest( + details: ClusterDetails, + uri: string, + method: string, + contentType: string, + body?: any, + ): Promise { + const bearerToken = details.serviceAccountToken; + if (!bearerToken) { + return { + code: ERROR_BAD_REQUEST, + data: { + error: 'Invalid service account token', + }, + }; + } + + const reqData: any = { + method, + headers: { + 'Content-Type': contentType, + Authorization: `Bearer ${bearerToken}`, + }, + }; + + if (!details.skipTLSVerify) { + if (details.caData) { + const ca = bufferFromFileOrString('', details.caData)?.toString() || ''; + reqData.agent = new https.Agent({ ca }); + } else { + this.logger.info('could not find CA certificate!'); + return { + code: ERROR_INTERNAL_SERVER, + data: { + error: 'Invalid CA certificate configured within Backstage', + }, + }; + } + } + + if (body && Object.keys(body).length > 0) { + reqData.body = JSON.stringify(body); + } + + try { + const req = await fetch(uri, reqData); + + let res; + if (contentType.includes(APPLICATION_JSON)) { + res = await req.json(); + } else { + res = await req.text(); + } + + const proxyResponse: KubernetesProxyResponse = { + code: req.status, + data: res, + cluster: details.name, + }; + + return proxyResponse; + } catch (e: any) { + return { + code: ERROR_INTERNAL_SERVER, + data: e, + cluster: details.name, + }; + } + } + + private getKubeConfig(clusterDetails: ClusterDetails): KubeConfig { + const cluster = { + name: clusterDetails.name, + server: clusterDetails.url, + skipTLSVerify: clusterDetails.skipTLSVerify, + caData: clusterDetails.caData, + }; + + const user = { + name: CLUSTER_USER_NAME, + token: clusterDetails.serviceAccountToken, + }; + + const context = { + name: clusterDetails.name, + user: user.name, + cluster: cluster.name, + }; + + const kc = new KubeConfig(); + if (clusterDetails.serviceAccountToken) { + kc.loadFromOptions({ + clusters: [cluster], + users: [user], + contexts: [context], + currentContext: context.name, + }); + } else { + kc.loadFromDefault(); + } + + return kc; + } + + private getBestResponseCode(codes: number[]): number { + const sorted = codes.sort(); + return sorted[0] ?? ERROR_INTERNAL_SERVER; + } +} diff --git a/plugins/kubernetes-backend/src/types/types.ts b/plugins/kubernetes-backend/src/types/types.ts index ed43935202..0af89b4d12 100644 --- a/plugins/kubernetes-backend/src/types/types.ts +++ b/plugins/kubernetes-backend/src/types/types.ts @@ -280,3 +280,11 @@ export interface KubernetesObjectsProvider { customResourcesByEntity: CustomResourcesByEntity, ): Promise; } + +/** + * + * @alpha + */ +export interface KubernetesProxyServices { + kcs: KubernetesClustersSupplier; +} diff --git a/plugins/kubernetes-common/api-report.md b/plugins/kubernetes-common/api-report.md index 8509fa97cc..21f8cd86f5 100644 --- a/plugins/kubernetes-common/api-report.md +++ b/plugins/kubernetes-common/api-report.md @@ -193,6 +193,16 @@ export interface KubernetesFetchError { statusCode?: number; } +// Warning: (ae-missing-release-tag) "KubernetesProxyClusters" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface KubernetesProxyClusters { + // (undocumented) + [key: string]: string; +} + +// Warning: (ae-missing-release-tag) "KubernetesRequestAuth" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// // @public (undocumented) export interface KubernetesRequestAuth { // (undocumented) diff --git a/plugins/kubernetes-common/src/types.ts b/plugins/kubernetes-common/src/types.ts index 3feddd7f4c..b1ed9165e2 100644 --- a/plugins/kubernetes-common/src/types.ts +++ b/plugins/kubernetes-common/src/types.ts @@ -258,3 +258,7 @@ export interface ClientPodStatus { memory: ClientCurrentResourceUsage; containers: ClientContainerStatus[]; } + +export interface KubernetesProxyClusters { + [key: string]: string; +} From e862980c57037018ec6efc52ade31c5221930850 Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Date: Fri, 28 Oct 2022 18:58:13 -0500 Subject: [PATCH 41/83] feat: Carlos Lopez pre RFC update commit squash docs: Remove unnecessary types test: Use MSW instead of mocking fetch fix: Updated api-report.md & error stringify from @backstage/errors feat: Kubernetes builder getters/setters update fix: Error handling with fix: Error handling with`@backstage/errors` fix: Use same MSW version as other plugins fix: Sort handleProxyRequest inputs fix: Small type & comment fixes fix: Change serverIP to serverURI fix: Variable name improvements Signed-off-by: Carlos Esteban Lopez --- plugins/kubernetes-backend/api-report.md | 38 +++- plugins/kubernetes-backend/package.json | 4 +- plugins/kubernetes-backend/src/index.ts | 1 + .../src/service/KubernetesBuilder.ts | 149 ++++++++++------ .../src/service/KubernetesProxy.test.ts | 162 ++++++++---------- .../src/service/KubernetesProxy.ts | 143 ++++++++-------- plugins/kubernetes-backend/src/types/types.ts | 8 - plugins/kubernetes-common/api-report.md | 4 - plugins/kubernetes-common/src/types.ts | 1 + yarn.lock | 3 + 10 files changed, 280 insertions(+), 233 deletions(-) diff --git a/plugins/kubernetes-backend/api-report.md b/plugins/kubernetes-backend/api-report.md index 303aaa3017..f5b8ff85b7 100644 --- a/plugins/kubernetes-backend/api-report.md +++ b/plugins/kubernetes-backend/api-report.md @@ -22,6 +22,8 @@ import { Logger } from 'winston'; import { Metrics } from '@kubernetes/client-node'; import type { ObjectsByEntityResponse } from '@backstage/plugin-kubernetes-common'; import { PluginEndpointDiscovery } from '@backstage/backend-common'; +import { PodStatus } from '@kubernetes/client-node/dist/top'; +import type { Request as Request_2 } from 'express'; import { TokenCredential } from '@azure/identity'; // @alpha (undocumented) @@ -188,6 +190,8 @@ export class KubernetesBuilder { options: KubernetesObjectsProviderOptions, ): KubernetesObjectsProvider; // (undocumented) + protected buildProxy(): KubernetesProxy; + // (undocumented) protected buildRouter( objectsProvider: KubernetesObjectsProvider, clusterSupplier: KubernetesClustersSupplier, @@ -207,9 +211,19 @@ export class KubernetesBuilder { clusterSupplier: KubernetesClustersSupplier, ): Promise; // (undocumented) + protected getClusterSupplier(): KubernetesClustersSupplier; + // (undocumented) + protected getFetcher(): KubernetesFetcher; + // (undocumented) + protected getObjectsProvider( + options: KubernetesObjectsProviderOptions, + ): KubernetesObjectsProvider; + // (undocumented) protected getObjectTypesToFetch(): ObjectToFetch[] | undefined; // (undocumented) - protected getProxyServices(): KubernetesProxyServices; + protected getProxy(): KubernetesProxy; + // (undocumented) + protected getServiceLocator(): KubernetesServiceLocator; // (undocumented) protected getServiceLocatorMethod(): ServiceLocatorMethod; // (undocumented) @@ -226,6 +240,8 @@ export class KubernetesBuilder { // (undocumented) setObjectsProvider(objectsProvider?: KubernetesObjectsProvider): this; // (undocumented) + setProxy(proxy?: KubernetesProxy): this; + // (undocumented) setServiceLocator(serviceLocator?: KubernetesServiceLocator): this; } @@ -330,9 +346,25 @@ export type KubernetesObjectTypes = | 'daemonsets'; // @alpha (undocumented) -export interface KubernetesProxyServices { +export class KubernetesProxy { + constructor(logger: Logger); // (undocumented) - kcs: KubernetesClustersSupplier; + handleProxyRequest( + req: Request_2, + clusterSupplier: KubernetesClustersSupplier, + ): Promise; + // (undocumented) + protected readonly logger: Logger; +} + +// @alpha (undocumented) +export interface KubernetesProxyResponse { + // (undocumented) + cluster?: string; + // (undocumented) + code: number; + // (undocumented) + data: any; } // @alpha diff --git a/plugins/kubernetes-backend/package.json b/plugins/kubernetes-backend/package.json index 95b3000069..d1352a21dc 100644 --- a/plugins/kubernetes-backend/package.json +++ b/plugins/kubernetes-backend/package.json @@ -36,6 +36,7 @@ "dependencies": { "@azure/identity": "^2.0.4", "@backstage/backend-common": "workspace:^", + "@backstage/backend-test-utils": "workspace:^", "@backstage/catalog-client": "workspace:^", "@backstage/catalog-model": "workspace:^", "@backstage/config": "workspace:^", @@ -56,8 +57,8 @@ "helmet": "^6.0.0", "lodash": "^4.17.21", "luxon": "^3.0.0", - "node-fetch": "^2.6.0", "morgan": "^1.10.0", + "node-fetch": "^2.6.0", "stream-buffers": "^3.0.2", "winston": "^3.2.1", "yn": "^4.0.0" @@ -66,6 +67,7 @@ "@backstage/cli": "workspace:^", "@types/aws4": "^1.5.1", "aws-sdk-mock": "^5.2.1", + "msw": "^0.48.0", "supertest": "^6.1.3" }, "files": [ diff --git a/plugins/kubernetes-backend/src/index.ts b/plugins/kubernetes-backend/src/index.ts index e2eee3f24e..fba5c4a151 100644 --- a/plugins/kubernetes-backend/src/index.ts +++ b/plugins/kubernetes-backend/src/index.ts @@ -32,6 +32,7 @@ export * from './kubernetes-auth-translator/types'; export * from './service/router'; export * from './service/KubernetesBuilder'; export * from './service/KubernetesClientProvider'; +export * from './service/KubernetesProxy'; export * from './types/types'; diff --git a/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts b/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts index c7f569267e..ff79bd83de 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts @@ -13,36 +13,34 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { CatalogApi } from '@backstage/catalog-client'; import { Config } from '@backstage/config'; import express from 'express'; import Router from 'express-promise-router'; -import { Logger } from 'winston'; import { Duration } from 'luxon'; +import { Logger } from 'winston'; + import { getCombinedClusterSupplier } from '../cluster-locator'; +import { addResourceRoutesToRouter } from '../routes/resourcesRoutes'; import { MultiTenantServiceLocator } from '../service-locator/MultiTenantServiceLocator'; import { - KubernetesObjectTypes, - ServiceLocatorMethod, CustomResource, - KubernetesObjectsProvider, - ObjectsByEntityRequest, KubernetesClustersSupplier, KubernetesFetcher, - KubernetesServiceLocator, + KubernetesObjectsProvider, KubernetesObjectsProviderOptions, - KubernetesProxyServices, + KubernetesObjectTypes, + KubernetesServiceLocator, + ObjectsByEntityRequest, + ServiceLocatorMethod, } from '../types/types'; import { KubernetesClientProvider } from './KubernetesClientProvider'; - -import { KubernetesProxy, KubernetesProxyResponse } from './KubernetesProxy'; - import { DEFAULT_OBJECTS, KubernetesFanOutHandler, } from './KubernetesFanOutHandler'; import { KubernetesClientBasedFetcher } from './KubernetesFetcher'; -import { addResourceRoutesToRouter } from '../routes/resourcesRoutes'; -import { CatalogApi } from '@backstage/catalog-client'; +import { KubernetesProxy, KubernetesProxyResponse } from './KubernetesProxy'; /** * @@ -80,15 +78,13 @@ export class KubernetesBuilder { private objectsProvider?: KubernetesObjectsProvider; private fetcher?: KubernetesFetcher; private serviceLocator?: KubernetesServiceLocator; - private proxy: KubernetesProxy; + private proxy?: KubernetesProxy; static createBuilder(env: KubernetesEnvironment) { return new KubernetesBuilder(env); } - constructor(protected readonly env: KubernetesEnvironment) { - this.proxy = new KubernetesProxy(env.logger); - } + constructor(protected readonly env: KubernetesEnvironment) {} public async build(): KubernetesBuilderReturn { const logger = this.env.logger; @@ -109,25 +105,19 @@ export class KubernetesBuilder { } const customResources = this.buildCustomResources(); - const fetcher = this.fetcher ?? this.buildFetcher(); + const fetcher = this.getFetcher(); - const clusterSupplier = - this.clusterSupplier ?? - this.buildClusterSupplier(this.defaultClusterRefreshInterval); + const clusterSupplier = this.getClusterSupplier(); - const serviceLocator = - this.serviceLocator ?? - this.buildServiceLocator(this.getServiceLocatorMethod(), clusterSupplier); + const serviceLocator = this.getServiceLocator(); - const objectsProvider = - this.objectsProvider ?? - this.buildObjectsProvider({ - logger, - fetcher, - serviceLocator, - customResources, - objectTypesToFetch: this.getObjectTypesToFetch(), - }); + const objectsProvider = this.getObjectsProvider({ + logger, + fetcher, + serviceLocator, + customResources, + objectTypesToFetch: this.getObjectTypesToFetch(), + }); const router = this.buildRouter( objectsProvider, @@ -170,6 +160,11 @@ export class KubernetesBuilder { return this; } + public setProxy(proxy?: KubernetesProxy) { + this.proxy = proxy; + return this; + } + protected buildCustomResources() { const customResources: CustomResource[] = ( this.env.config.getOptionalConfigArray('kubernetes.customResources') ?? [] @@ -193,24 +188,29 @@ export class KubernetesBuilder { refreshInterval: Duration, ): KubernetesClustersSupplier { const config = this.env.config; - return getCombinedClusterSupplier( + this.clusterSupplier = getCombinedClusterSupplier( config, this.env.catalogApi, refreshInterval, ); + + return this.clusterSupplier; } protected buildObjectsProvider( options: KubernetesObjectsProviderOptions, ): KubernetesObjectsProvider { - return new KubernetesFanOutHandler(options); + this.objectsProvider = new KubernetesFanOutHandler(options); + return this.objectsProvider; } protected buildFetcher(): KubernetesFetcher { - return new KubernetesClientBasedFetcher({ + this.fetcher = new KubernetesClientBasedFetcher({ kubernetesClientProvider: new KubernetesClientProvider(), logger: this.env.logger, }); + + return this.fetcher; } protected buildServiceLocator( @@ -219,14 +219,19 @@ export class KubernetesBuilder { ): KubernetesServiceLocator { switch (method) { case 'multiTenant': - return this.buildMultiTenantServiceLocator(clusterSupplier); + this.serviceLocator = + this.buildMultiTenantServiceLocator(clusterSupplier); + break; case 'http': - return this.buildHttpServiceLocator(clusterSupplier); + this.serviceLocator = this.buildHttpServiceLocator(clusterSupplier); + break; default: throw new Error( `Unsupported kubernetes.clusterLocatorMethod "${method}"`, ); } + + return this.serviceLocator; } protected buildMultiTenantServiceLocator( @@ -241,6 +246,11 @@ export class KubernetesBuilder { throw new Error('not implemented'); } + protected buildProxy(): KubernetesProxy { + this.proxy = new KubernetesProxy(this.env.logger); + return this.proxy; + } + protected buildRouter( objectsProvider: KubernetesObjectsProvider, clusterSupplier: KubernetesClustersSupplier, @@ -250,6 +260,8 @@ export class KubernetesBuilder { const router = Router(); router.use(express.json()); + const proxy = this.getProxy(); + // @deprecated router.post('/services/:serviceId', async (req, res) => { const serviceId = req.params.serviceId; @@ -280,11 +292,13 @@ export class KubernetesBuilder { }); }); - router.get('/proxy/:encodedQuery', this.makeProxyRequest.bind(this)); - router.post('/proxy/:encodedQuery', this.makeProxyRequest.bind(this)); - router.put('/proxy/:encodedQuery', this.makeProxyRequest.bind(this)); - router.patch('/proxy/:encodedQuery', this.makeProxyRequest.bind(this)); - router.delete('/proxy/:encodedQuery', this.makeProxyRequest.bind(this)); + if (typeof proxy?.handleProxyRequest === 'function') { + router.get('/proxy/:encodedQuery', this.makeProxyRequest.bind(this)); + router.post('/proxy/:encodedQuery', this.makeProxyRequest.bind(this)); + router.put('/proxy/:encodedQuery', this.makeProxyRequest.bind(this)); + router.patch('/proxy/:encodedQuery', this.makeProxyRequest.bind(this)); + router.delete('/proxy/:encodedQuery', this.makeProxyRequest.bind(this)); + } addResourceRoutesToRouter(router, catalogApi, objectsProvider); @@ -309,6 +323,31 @@ export class KubernetesBuilder { ) as ServiceLocatorMethod; } + protected getFetcher(): KubernetesFetcher { + return this.fetcher ?? this.buildFetcher(); + } + + protected getClusterSupplier() { + return ( + this.clusterSupplier ?? + this.buildClusterSupplier(this.defaultClusterRefreshInterval) + ); + } + + protected getServiceLocator(): KubernetesServiceLocator { + return ( + this.serviceLocator ?? + this.buildServiceLocator( + this.getServiceLocatorMethod(), + this.getClusterSupplier(), + ) + ); + } + + protected getObjectsProvider(options: KubernetesObjectsProviderOptions) { + return this.objectsProvider ?? this.buildObjectsProvider(options); + } + protected getObjectTypesToFetch() { const objectTypesToFetchStrings = this.env.config.getOptionalStringArray( 'kubernetes.objectTypes', @@ -339,27 +378,27 @@ export class KubernetesBuilder { return objectTypesToFetch; } + protected getProxy() { + return this.proxy ?? this.buildProxy(); + } + protected async makeProxyRequest( req: express.Request, res: express.Response, ) { - const services = this.getProxyServices(); + const supplier = this.getClustersSupplier(); + const proxy = this.getProxy(); + const proxyResponse: KubernetesProxyResponse = - await this.proxy.handleProxyRequest(services, req); + await proxy.handleProxyRequest(req, supplier); + res.status(proxyResponse.code).json(proxyResponse.data); } - protected getProxyServices(): KubernetesProxyServices { - const kcs = + private getClustersSupplier(): KubernetesClustersSupplier { + return ( this.clusterSupplier ?? - this.buildClusterSupplier(this.defaultClusterRefreshInterval); - - if (!kcs) { - this.env.logger.error('could not find cluster supplier!'); - } - - return { - kcs, - }; + this.buildClusterSupplier(this.defaultClusterRefreshInterval) + ); } } diff --git a/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts b/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts index c692355fbb..b9bb1d425f 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts @@ -13,32 +13,27 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -import { getVoidLogger } from '@backstage/backend-common'; -import { - ClusterDetails, - KubernetesClustersSupplier, - KubernetesProxyServices, -} from '../types/types'; -import { KubernetesProxy } from './KubernetesProxy'; - -import { Request } from 'express'; - import 'buffer'; -jest.mock('node-fetch'); -const { Response } = jest.requireActual('node-fetch'); +import { getVoidLogger } from '@backstage/backend-common'; +import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { Request } from 'express'; +import { rest } from 'msw'; +import { setupServer } from 'msw/node'; -import fetch from 'node-fetch'; +import { ClusterDetails, KubernetesClustersSupplier } from '../types/types'; +import { KubernetesProxy } from './KubernetesProxy'; +import { NotFoundError } from '@backstage/errors'; describe('KubernetesProxy', () => { - let _clientMock: any; - let sut: KubernetesProxy; + let proxy: KubernetesProxy; + const worker = setupServer(); + setupRequestMockHandlers(worker); const buildEncodedRequest = ( clustersHeader: any, query: string, - body?: any, + body?: unknown, ): Request => { const encodedQuery = encodeURIComponent(query); const encodedClusters = Buffer.from( @@ -75,41 +70,29 @@ describe('KubernetesProxy', () => { return req; }; - const buildProxyServicesWithClusters = ( + const buildClustersSupplierWithClusters = ( clusters: ClusterDetails[], - ): KubernetesProxyServices => { - const kcs: KubernetesClustersSupplier = { - getClusters: async () => { - return clusters; - }, - }; - - return { - kcs, - }; - }; - - beforeEach(() => { - jest.resetAllMocks(); - _clientMock = { - handleProxyRequest: jest.fn(), - }; - - sut = new KubernetesProxy(getVoidLogger()); + ): KubernetesClustersSupplier => ({ + getClusters: async () => { + return clusters; + }, }); - it('should return a 404 if no clusters are found', async () => { - const services = buildProxyServicesWithClusters([]); + beforeEach(() => { + proxy = new KubernetesProxy(getVoidLogger()); + }); + + it('should return a ERROR_NOT_FOUND if no clusters are found', async () => { + const clustersSupplier = buildClustersSupplierWithClusters([]); const req = buildEncodedRequest({}, 'api'); - const result = await sut.handleProxyRequest(services, req); - - expect(result.code).toEqual(404); - expect(fetch).not.toHaveBeenCalled(); + await expect( + proxy.handleProxyRequest(req, clustersSupplier), + ).rejects.toThrow(NotFoundError); }); it('should match the response code of the Kubernetes response (single cluster)', async () => { - const services = buildProxyServicesWithClusters([ + const clusters: ClusterDetails[] = [ { name: 'cluster1', url: 'http://localhost:9999', @@ -117,7 +100,9 @@ describe('KubernetesProxy', () => { authProvider: 'serviceAccount', skipTLSVerify: true, }, - ]); + ]; + + const clustersSupplier = buildClustersSupplierWithClusters(clusters); const req = buildEncodedRequest({ cluster1: 'token' }, 'api'); const apiResponse = { @@ -131,21 +116,19 @@ describe('KubernetesProxy', () => { ], }; - // @ts-ignore-next-line - (fetch as jest.MockedFunction).mockResolvedValue( - new Response(JSON.stringify(apiResponse), { - status: 299, - }), + worker.use( + rest.get(`${clusters[0].url}/${req.params.encodedQuery}`, (_, res, ctx) => + res(ctx.status(299), ctx.body(JSON.stringify(apiResponse))), + ), ); - const result = await sut.handleProxyRequest(services, req); + const result = await proxy.handleProxyRequest(req, clustersSupplier); - expect(fetch).toBeCalledTimes(1); expect(result.code).toEqual(299); }); it('should match the response code of the best Kubernetes response (multi cluster)', async () => { - const services = buildProxyServicesWithClusters([ + const clusters: ClusterDetails[] = [ { name: 'cluster1', url: 'http://localhost:9998', @@ -160,7 +143,9 @@ describe('KubernetesProxy', () => { authProvider: 'serviceAccount', skipTLSVerify: true, }, - ]); + ]; + + const clustersSupplier = buildClustersSupplierWithClusters(clusters); const req = buildEncodedRequest( { cluster1: 'token', cluster2: 'token' }, 'api', @@ -187,26 +172,22 @@ describe('KubernetesProxy', () => { code: 401, }; - (fetch as jest.MockedFunction) - .mockResolvedValueOnce( - new Response(JSON.stringify(apiResponse1), { - status: 200, - }), - ) - .mockResolvedValueOnce( - new Response(JSON.stringify(apiResponse2), { - status: 401, - }), - ); + worker.use( + rest.get(`${clusters[0].url}/${req.params.encodedQuery}`, (_, res, ctx) => + res(ctx.status(200), ctx.body(JSON.stringify(apiResponse1))), + ), + rest.get(`${clusters[1].url}/${req.params.encodedQuery}`, (_, res, ctx) => + res(ctx.status(401), ctx.body(JSON.stringify(apiResponse2))), + ), + ); - const result = await sut.handleProxyRequest(services, req); + const result = await proxy.handleProxyRequest(req, clustersSupplier); - expect(fetch).toBeCalledTimes(2); expect(result.code).toEqual(200); }); it('should pass the exact response data from Kubernetes (single cluster)', async () => { - const services = buildProxyServicesWithClusters([ + const clusters: ClusterDetails[] = [ { name: 'cluster1', url: 'http://localhost:9999', @@ -214,7 +195,9 @@ describe('KubernetesProxy', () => { authProvider: 'serviceAccount', skipTLSVerify: true, }, - ]); + ]; + + const clustersSupplier = buildClustersSupplierWithClusters(clusters); const req = buildEncodedRequest({ cluster1: 'token' }, 'api'); const apiResponse = { @@ -228,14 +211,13 @@ describe('KubernetesProxy', () => { ], }; - // @ts-ignore-next-line - (fetch as jest.MockedFunction).mockResolvedValue( - new Response(JSON.stringify(apiResponse), { - status: 200, - }), + worker.use( + rest.get(`${clusters[0].url}/${req.params.encodedQuery}`, (_, res, ctx) => + res(ctx.status(200), ctx.body(JSON.stringify(apiResponse))), + ), ); - const result = await sut.handleProxyRequest(services, req); + const result = await proxy.handleProxyRequest(req, clustersSupplier); const resultString = JSON.stringify(result.data); const expectedString = JSON.stringify({ @@ -251,12 +233,11 @@ describe('KubernetesProxy', () => { }, }); - expect(fetch).toBeCalledTimes(1); expect(resultString).toEqual(expectedString); }); it('should pass the exact response data from Kubernetes (multi cluster)', async () => { - const services = buildProxyServicesWithClusters([ + const clusters: ClusterDetails[] = [ { name: 'cluster1', url: 'http://localhost:9998', @@ -271,7 +252,9 @@ describe('KubernetesProxy', () => { authProvider: 'serviceAccount', skipTLSVerify: true, }, - ]); + ]; + + const clustersSupplier = buildClustersSupplierWithClusters(clusters); const req = buildEncodedRequest( { cluster1: 'token', cluster2: 'token' }, 'api', @@ -298,20 +281,16 @@ describe('KubernetesProxy', () => { code: 401, }; - // @ts-ignore-next-line - (fetch as jest.MockedFunction) - .mockResolvedValueOnce( - new Response(JSON.stringify(apiResponse1), { - status: 200, - }), - ) - .mockResolvedValueOnce( - new Response(JSON.stringify(apiResponse2), { - status: 401, - }), - ); + worker.use( + rest.get(`${clusters[0].url}/${req.params.encodedQuery}`, (_, res, ctx) => + res(ctx.status(200), ctx.body(JSON.stringify(apiResponse1))), + ), + rest.get(`${clusters[1].url}/${req.params.encodedQuery}`, (_, res, ctx) => + res(ctx.status(401), ctx.body(JSON.stringify(apiResponse2))), + ), + ); - const result = await sut.handleProxyRequest(services, req); + const result = await proxy.handleProxyRequest(req, clustersSupplier); const resultString = JSON.stringify(result.data); const expectedString = JSON.stringify({ @@ -336,7 +315,6 @@ describe('KubernetesProxy', () => { }, }); - expect(fetch).toBeCalledTimes(2); expect(resultString).toEqual(expectedString); }); }); diff --git a/plugins/kubernetes-backend/src/service/KubernetesProxy.ts b/plugins/kubernetes-backend/src/service/KubernetesProxy.ts index e073ab3ec1..dea4786820 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesProxy.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesProxy.ts @@ -13,69 +13,81 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -import { KubeConfig, bufferFromFileOrString } from '@kubernetes/client-node'; -import { Logger } from 'winston'; -import fetch from 'node-fetch'; +import { + AuthenticationError, + ConflictError, + ForwardedError, + InputError, + NotFoundError, + stringifyError, +} from '@backstage/errors'; +import { bufferFromFileOrString, KubeConfig } from '@kubernetes/client-node'; import * as https from 'https'; +import fetch, { RequestInit } from 'node-fetch'; +import { Logger } from 'winston'; + +import { ClusterDetails, KubernetesClustersSupplier } from '../types/types'; import type { Request } from 'express'; -import { - ClusterDetails, - KubernetesProxyServices, - KubernetesClustersSupplier, -} from '../types/types'; - const HEADER_CONTENT_TYPE: string = 'Content-Type'; const APPLICATION_JSON: string = 'application/json'; const HEADER_KUBERNETES_CLUSTERS: string = 'X-Kubernetes-Clusters'; -const ERROR_BAD_REQUEST: number = 400; -const ERROR_NOT_FOUND: number = 404; const ERROR_INTERNAL_SERVER: number = 500; const CLUSTER_USER_NAME: string = 'backstage'; +/** + * + * @alpha + */ export interface KubernetesProxyResponse { code: number; data: any; cluster?: string; } +/** + * + * @alpha + */ interface KubernetesProxyClusters { [key: string]: string; } +/** + * + * @alpha + */ export class KubernetesProxy { constructor(protected readonly logger: Logger) {} public async handleProxyRequest( - services: KubernetesProxyServices, req: Request, + clusterSupplier: KubernetesClustersSupplier, ): Promise { - const krc = this.getKubernetesRequestedClusters(req); + const requestedClusters = this.getKubernetesRequestedClusters(req); - if (Object.keys(krc).length < 1) { - return { - code: ERROR_NOT_FOUND, - data: 'No clusters found!', - }; + if (Object.keys(requestedClusters).length < 1) { + this.logger.error(`No clusters found`); + throw new NotFoundError('No clusters found!'); } - const details = await this.getClusterDetails(services.kcs, krc); + const clusterDetails = await this.getClusterDetails( + clusterSupplier, + requestedClusters, + ); - if (details.length < 1) { - return { - code: ERROR_NOT_FOUND, - data: 'No clusters found!', - }; + if (clusterDetails.length < 1) { + this.logger.error(`No clusters found`); + throw new NotFoundError('No clusters found!'); } const responses = await Promise.all( - details.map(async d => { - const response = await this.makeRequestToCluster(d, req); + clusterDetails.map(async clusterDetail => { + const response = await this.makeRequestToCluster(clusterDetail, req); return response; }), ); @@ -116,7 +128,7 @@ export class KubernetesProxy { return clusters; } catch (e: any) { this.logger.debug( - `error with encoded cluster header: ${JSON.stringify(e)}`, + `error with encoded cluster header: ${stringifyError(e)}`, ); } return {}; @@ -124,17 +136,17 @@ export class KubernetesProxy { private async getClusterDetails( clusterSupplier: KubernetesClustersSupplier, - krc: KubernetesProxyClusters, + requestedClusters: KubernetesProxyClusters, ): Promise { const clusters = await clusterSupplier.getClusters(); - const clusterNames = Object.keys(krc); + const clusterNames = Object.keys(requestedClusters); const clusterDetails = clusters.filter(c => clusterNames.includes(c.name)); const clusterDetailsAuth = clusterDetails.map(c => { const cAuth: ClusterDetails = Object.assign(c, { - serviceAccountToken: krc[c.name], + serviceAccountToken: requestedClusters[c.name], }); return cAuth; }); @@ -151,28 +163,26 @@ export class KubernetesProxy { details: ClusterDetails, req: Request, ): Promise { - const serverIP = this.getClusterURI(details); - if (!serverIP) { - return { - code: ERROR_INTERNAL_SERVER, - data: null, - }; + const serverURI = this.getClusterURI(details); + + if (!serverURI) { + this.logger.error(`Cluster ${details.name} details IP error`); + + throw new ConflictError('Cluster detail error'); } const query = decodeURIComponent(req.params.encodedQuery) || ''; - const uri = `${serverIP}/${query}`; + const uri = `${serverURI}/${query}`; const contentType = req.header(HEADER_CONTENT_TYPE) || APPLICATION_JSON; - const res = await this.sendClusterRequest( + return await this.sendClusterRequest( details, uri, req.method, contentType, req.body, ); - - return res; } private async sendClusterRequest( @@ -183,16 +193,14 @@ export class KubernetesProxy { body?: any, ): Promise { const bearerToken = details.serviceAccountToken; + if (!bearerToken) { - return { - code: ERROR_BAD_REQUEST, - data: { - error: 'Invalid service account token', - }, - }; + this.logger.error('Invalid service account token'); + + throw new AuthenticationError('Invalid service account token'); } - const reqData: any = { + const reqData: RequestInit = { method, headers: { 'Content-Type': contentType, @@ -205,13 +213,10 @@ export class KubernetesProxy { const ca = bufferFromFileOrString('', details.caData)?.toString() || ''; reqData.agent = new https.Agent({ ca }); } else { - this.logger.info('could not find CA certificate!'); - return { - code: ERROR_INTERNAL_SERVER, - data: { - error: 'Invalid CA certificate configured within Backstage', - }, - }; + this.logger.error('could not find CA certificate!'); + throw new InputError( + 'Invalid CA certificate configured within Backstage', + ); } } @@ -220,28 +225,25 @@ export class KubernetesProxy { } try { - const req = await fetch(uri, reqData); + const res = await fetch(uri, reqData); + + let data: string | any; - let res; if (contentType.includes(APPLICATION_JSON)) { - res = await req.json(); + data = await res.json(); } else { - res = await req.text(); + data = await res.text(); } const proxyResponse: KubernetesProxyResponse = { - code: req.status, - data: res, + code: res.status, + data, cluster: details.name, }; return proxyResponse; } catch (e: any) { - return { - code: ERROR_INTERNAL_SERVER, - data: e, - cluster: details.name, - }; + throw new ForwardedError(`Cluster ${details.name} request error`, e); } } @@ -264,19 +266,20 @@ export class KubernetesProxy { cluster: cluster.name, }; - const kc = new KubeConfig(); + const kubeConfig = new KubeConfig(); + if (clusterDetails.serviceAccountToken) { - kc.loadFromOptions({ + kubeConfig.loadFromOptions({ clusters: [cluster], users: [user], contexts: [context], currentContext: context.name, }); } else { - kc.loadFromDefault(); + kubeConfig.loadFromDefault(); } - return kc; + return kubeConfig; } private getBestResponseCode(codes: number[]): number { diff --git a/plugins/kubernetes-backend/src/types/types.ts b/plugins/kubernetes-backend/src/types/types.ts index 0af89b4d12..ed43935202 100644 --- a/plugins/kubernetes-backend/src/types/types.ts +++ b/plugins/kubernetes-backend/src/types/types.ts @@ -280,11 +280,3 @@ export interface KubernetesObjectsProvider { customResourcesByEntity: CustomResourcesByEntity, ): Promise; } - -/** - * - * @alpha - */ -export interface KubernetesProxyServices { - kcs: KubernetesClustersSupplier; -} diff --git a/plugins/kubernetes-common/api-report.md b/plugins/kubernetes-common/api-report.md index 21f8cd86f5..c504558b00 100644 --- a/plugins/kubernetes-common/api-report.md +++ b/plugins/kubernetes-common/api-report.md @@ -193,16 +193,12 @@ export interface KubernetesFetchError { statusCode?: number; } -// Warning: (ae-missing-release-tag) "KubernetesProxyClusters" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export interface KubernetesProxyClusters { // (undocumented) [key: string]: string; } -// Warning: (ae-missing-release-tag) "KubernetesRequestAuth" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export interface KubernetesRequestAuth { // (undocumented) diff --git a/plugins/kubernetes-common/src/types.ts b/plugins/kubernetes-common/src/types.ts index b1ed9165e2..d0bf7757fb 100644 --- a/plugins/kubernetes-common/src/types.ts +++ b/plugins/kubernetes-common/src/types.ts @@ -259,6 +259,7 @@ export interface ClientPodStatus { containers: ClientContainerStatus[]; } +/** @public */ export interface KubernetesProxyClusters { [key: string]: string; } diff --git a/yarn.lock b/yarn.lock index 8ca56c7fcf..ae10e493f5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5964,6 +5964,7 @@ __metadata: dependencies: "@azure/identity": ^2.0.4 "@backstage/backend-common": "workspace:^" + "@backstage/backend-test-utils": "workspace:^" "@backstage/catalog-client": "workspace:^" "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" @@ -5988,6 +5989,8 @@ __metadata: lodash: ^4.17.21 luxon: ^3.0.0 morgan: ^1.10.0 + msw: ^0.48.0 + node-fetch: ^2.6.0 stream-buffers: ^3.0.2 supertest: ^6.1.3 winston: ^3.2.1 From 9fb0d696b88a92a8e5204d3d89291f67f460d8d7 Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Date: Tue, 1 Nov 2022 14:28:58 -0500 Subject: [PATCH 42/83] feat: Remove multi-cluster support per latest RFC version Signed-off-by: Carlos Esteban Lopez --- plugins/kubernetes-backend/api-report.md | 31 +-- plugins/kubernetes-backend/package.json | 3 +- .../src/service/KubernetesBuilder.ts | 40 +-- .../src/service/KubernetesProxy.test.ts | 241 +++--------------- .../src/service/KubernetesProxy.ts | 228 ++++++----------- yarn.lock | 12 +- 6 files changed, 159 insertions(+), 396 deletions(-) diff --git a/plugins/kubernetes-backend/api-report.md b/plugins/kubernetes-backend/api-report.md index f5b8ff85b7..827ec5e74c 100644 --- a/plugins/kubernetes-backend/api-report.md +++ b/plugins/kubernetes-backend/api-report.md @@ -22,10 +22,12 @@ import { Logger } from 'winston'; import { Metrics } from '@kubernetes/client-node'; import type { ObjectsByEntityResponse } from '@backstage/plugin-kubernetes-common'; import { PluginEndpointDiscovery } from '@backstage/backend-common'; -import { PodStatus } from '@kubernetes/client-node/dist/top'; -import type { Request as Request_2 } from 'express'; +import type { RequestHandler } from 'express'; import { TokenCredential } from '@azure/identity'; +// @alpha (undocumented) +export const APPLICATION_JSON: string; + // @alpha (undocumented) export interface AWSClusterDetails extends ClusterDetails { // (undocumented) @@ -144,6 +146,9 @@ export class GoogleServiceAccountAuthTranslator ): Promise; } +// @alpha (undocumented) +export const HEADER_KUBERNETES_CLUSTER: string; + // @alpha (undocumented) export interface KubernetesAuthTranslator { // (undocumented) @@ -227,11 +232,6 @@ export class KubernetesBuilder { // (undocumented) protected getServiceLocatorMethod(): ServiceLocatorMethod; // (undocumented) - protected makeProxyRequest( - req: express.Request, - res: express.Response, - ): Promise; - // (undocumented) setClusterSupplier(clusterSupplier?: KubernetesClustersSupplier): this; // (undocumented) setDefaultClusterRefreshInterval(refreshInterval: Duration): this; @@ -251,6 +251,7 @@ export type KubernetesBuilderReturn = Promise<{ clusterSupplier: KubernetesClustersSupplier; customResources: CustomResource[]; fetcher: KubernetesFetcher; + proxy: KubernetesProxy; objectsProvider: KubernetesObjectsProvider; serviceLocator: KubernetesServiceLocator; }>; @@ -349,22 +350,14 @@ export type KubernetesObjectTypes = export class KubernetesProxy { constructor(logger: Logger); // (undocumented) - handleProxyRequest( - req: Request_2, - clusterSupplier: KubernetesClustersSupplier, - ): Promise; + get clustersSupplier(): KubernetesClustersSupplier; + set clustersSupplier(clustersSupplier: KubernetesClustersSupplier); // (undocumented) protected readonly logger: Logger; -} - -// @alpha (undocumented) -export interface KubernetesProxyResponse { // (undocumented) - cluster?: string; + static readonly PROXY_PATH: string; // (undocumented) - code: number; - // (undocumented) - data: any; + proxyRequestHandler: RequestHandler; } // @alpha diff --git a/plugins/kubernetes-backend/package.json b/plugins/kubernetes-backend/package.json index d1352a21dc..d5ab468790 100644 --- a/plugins/kubernetes-backend/package.json +++ b/plugins/kubernetes-backend/package.json @@ -44,6 +44,7 @@ "@backstage/plugin-auth-node": "workspace:^", "@backstage/plugin-kubernetes-common": "workspace:^", "@google-cloud/container": "^4.0.0", + "@jest-mock/express": "^2.0.1", "@kubernetes/client-node": "0.17.0", "@types/express": "^4.17.6", "@types/luxon": "^3.0.0", @@ -58,7 +59,7 @@ "lodash": "^4.17.21", "luxon": "^3.0.0", "morgan": "^1.10.0", - "node-fetch": "^2.6.0", + "node-fetch": "^2.6.7", "stream-buffers": "^3.0.2", "winston": "^3.2.1", "yn": "^4.0.0" diff --git a/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts b/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts index ff79bd83de..3ac27decc8 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts @@ -40,7 +40,7 @@ import { KubernetesFanOutHandler, } from './KubernetesFanOutHandler'; import { KubernetesClientBasedFetcher } from './KubernetesFetcher'; -import { KubernetesProxy, KubernetesProxyResponse } from './KubernetesProxy'; +import { KubernetesProxy } from './KubernetesProxy'; /** * @@ -62,6 +62,7 @@ export type KubernetesBuilderReturn = Promise<{ clusterSupplier: KubernetesClustersSupplier; customResources: CustomResource[]; fetcher: KubernetesFetcher; + proxy: KubernetesProxy; objectsProvider: KubernetesObjectsProvider; serviceLocator: KubernetesServiceLocator; }>; @@ -107,8 +108,12 @@ export class KubernetesBuilder { const fetcher = this.getFetcher(); + const proxy = this.getProxy(); + const clusterSupplier = this.getClusterSupplier(); + proxy.clustersSupplier = clusterSupplier; + const serviceLocator = this.getServiceLocator(); const objectsProvider = this.getObjectsProvider({ @@ -129,6 +134,7 @@ export class KubernetesBuilder { clusterSupplier, customResources, fetcher, + proxy, objectsProvider, router, serviceLocator, @@ -292,12 +298,12 @@ export class KubernetesBuilder { }); }); - if (typeof proxy?.handleProxyRequest === 'function') { - router.get('/proxy/:encodedQuery', this.makeProxyRequest.bind(this)); - router.post('/proxy/:encodedQuery', this.makeProxyRequest.bind(this)); - router.put('/proxy/:encodedQuery', this.makeProxyRequest.bind(this)); - router.patch('/proxy/:encodedQuery', this.makeProxyRequest.bind(this)); - router.delete('/proxy/:encodedQuery', this.makeProxyRequest.bind(this)); + if (typeof proxy?.proxyRequestHandler === 'function') { + router.get(KubernetesProxy.PROXY_PATH, proxy.proxyRequestHandler); + router.post(KubernetesProxy.PROXY_PATH, proxy.proxyRequestHandler); + router.put(KubernetesProxy.PROXY_PATH, proxy.proxyRequestHandler); + router.patch(KubernetesProxy.PROXY_PATH, proxy.proxyRequestHandler); + router.delete(KubernetesProxy.PROXY_PATH, proxy.proxyRequestHandler); } addResourceRoutesToRouter(router, catalogApi, objectsProvider); @@ -381,24 +387,4 @@ export class KubernetesBuilder { protected getProxy() { return this.proxy ?? this.buildProxy(); } - - protected async makeProxyRequest( - req: express.Request, - res: express.Response, - ) { - const supplier = this.getClustersSupplier(); - const proxy = this.getProxy(); - - const proxyResponse: KubernetesProxyResponse = - await proxy.handleProxyRequest(req, supplier); - - res.status(proxyResponse.code).json(proxyResponse.data); - } - - private getClustersSupplier(): KubernetesClustersSupplier { - return ( - this.clusterSupplier ?? - this.buildClusterSupplier(this.defaultClusterRefreshInterval) - ); - } } diff --git a/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts b/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts index b9bb1d425f..adf9357bb3 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts @@ -22,50 +22,38 @@ import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { ClusterDetails, KubernetesClustersSupplier } from '../types/types'; -import { KubernetesProxy } from './KubernetesProxy'; +import { + APPLICATION_JSON, + HEADER_KUBERNETES_CLUSTER, + KubernetesProxy, +} from './KubernetesProxy'; import { NotFoundError } from '@backstage/errors'; +import { getMockReq, getMockRes } from '@jest-mock/express'; describe('KubernetesProxy', () => { let proxy: KubernetesProxy; const worker = setupServer(); setupRequestMockHandlers(worker); - const buildEncodedRequest = ( - clustersHeader: any, - query: string, - body?: unknown, - ): Request => { - const encodedQuery = encodeURIComponent(query); - const encodedClusters = Buffer.from( - JSON.stringify(clustersHeader), - ).toString('base64'); - - const req = { + const buildMockRequest = (clusterName: any, path: string): Request => { + const req = getMockReq({ params: { - encodedQuery, + path, }, - header: (key: string) => { - let value: string = ''; + header: jest.fn((key: string) => { switch (key) { case 'Content-Type': { - value = 'application/json'; - break; + return APPLICATION_JSON; } - case 'X-Kubernetes-Clusters': { - value = encodedClusters; - break; + case HEADER_KUBERNETES_CLUSTER: { + return clusterName; } default: { - break; + return ''; } } - return value; - }, - } as unknown as Request; - - if (body) { - req.body = body; - } + }), + }); return req; }; @@ -83,15 +71,17 @@ describe('KubernetesProxy', () => { }); it('should return a ERROR_NOT_FOUND if no clusters are found', async () => { - const clustersSupplier = buildClustersSupplierWithClusters([]); - const req = buildEncodedRequest({}, 'api'); + proxy.clustersSupplier = buildClustersSupplierWithClusters([]); - await expect( - proxy.handleProxyRequest(req, clustersSupplier), - ).rejects.toThrow(NotFoundError); + const req = buildMockRequest('test', 'api'); + const { res, next } = getMockRes(); + + await expect(proxy.proxyRequestHandler(req, res, next)).rejects.toThrow( + NotFoundError, + ); }); - it('should match the response code of the Kubernetes response (single cluster)', async () => { + it('should match the response code of the Kubernetes response', async () => { const clusters: ClusterDetails[] = [ { name: 'cluster1', @@ -102,8 +92,10 @@ describe('KubernetesProxy', () => { }, ]; - const clustersSupplier = buildClustersSupplierWithClusters(clusters); - const req = buildEncodedRequest({ cluster1: 'token' }, 'api'); + proxy.clustersSupplier = buildClustersSupplierWithClusters(clusters); + + const req = buildMockRequest('cluster1', 'api'); + const { res: response, next } = getMockRes(); const apiResponse = { kind: 'APIVersions', @@ -117,76 +109,18 @@ describe('KubernetesProxy', () => { }; worker.use( - rest.get(`${clusters[0].url}/${req.params.encodedQuery}`, (_, res, ctx) => + rest.get(`${clusters[0].url}/${req.params.path}`, (_, res, ctx) => res(ctx.status(299), ctx.body(JSON.stringify(apiResponse))), ), ); - const result = await proxy.handleProxyRequest(req, clustersSupplier); + await proxy.proxyRequestHandler(req, response, next); - expect(result.code).toEqual(299); + expect(response.status).toHaveBeenCalledWith(299); + expect(response.json).toHaveBeenCalledWith(apiResponse); }); - it('should match the response code of the best Kubernetes response (multi cluster)', async () => { - const clusters: ClusterDetails[] = [ - { - name: 'cluster1', - url: 'http://localhost:9998', - serviceAccountToken: 'token', - authProvider: 'serviceAccount', - skipTLSVerify: true, - }, - { - name: 'cluster2', - url: 'http://localhost:9999', - serviceAccountToken: 'token', - authProvider: 'serviceAccount', - skipTLSVerify: true, - }, - ]; - - const clustersSupplier = buildClustersSupplierWithClusters(clusters); - const req = buildEncodedRequest( - { cluster1: 'token', cluster2: 'token' }, - 'api', - ); - - const apiResponse1 = { - kind: 'APIVersions', - versions: ['v1'], - serverAddressByClientCIDRs: [ - { - clientCIDR: '0.0.0.0/0', - serverAddress: '192.168.0.1:3333', - }, - ], - }; - - const apiResponse2 = { - kind: 'Status', - apiVersion: 'v1', - metadata: {}, - status: 'Failure', - message: 'Unauthorized', - reason: 'Unauthorized', - code: 401, - }; - - worker.use( - rest.get(`${clusters[0].url}/${req.params.encodedQuery}`, (_, res, ctx) => - res(ctx.status(200), ctx.body(JSON.stringify(apiResponse1))), - ), - rest.get(`${clusters[1].url}/${req.params.encodedQuery}`, (_, res, ctx) => - res(ctx.status(401), ctx.body(JSON.stringify(apiResponse2))), - ), - ); - - const result = await proxy.handleProxyRequest(req, clustersSupplier); - - expect(result.code).toEqual(200); - }); - - it('should pass the exact response data from Kubernetes (single cluster)', async () => { + it('should pass the exact response data from Kubernetes', async () => { const clusters: ClusterDetails[] = [ { name: 'cluster1', @@ -197,8 +131,10 @@ describe('KubernetesProxy', () => { }, ]; - const clustersSupplier = buildClustersSupplierWithClusters(clusters); - const req = buildEncodedRequest({ cluster1: 'token' }, 'api'); + proxy.clustersSupplier = buildClustersSupplierWithClusters(clusters); + + const req = buildMockRequest('cluster1', 'api'); + const { res: response, next } = getMockRes(); const apiResponse = { kind: 'APIVersions', @@ -212,109 +148,14 @@ describe('KubernetesProxy', () => { }; worker.use( - rest.get(`${clusters[0].url}/${req.params.encodedQuery}`, (_, res, ctx) => + rest.get(`${clusters[0].url}/${req.params.path}`, (_, res, ctx) => res(ctx.status(200), ctx.body(JSON.stringify(apiResponse))), ), ); - const result = await proxy.handleProxyRequest(req, clustersSupplier); + await proxy.proxyRequestHandler(req, response, next); - const resultString = JSON.stringify(result.data); - const expectedString = JSON.stringify({ - cluster1: { - kind: 'APIVersions', - versions: ['v1'], - serverAddressByClientCIDRs: [ - { - clientCIDR: '0.0.0.0/0', - serverAddress: '192.168.0.1:3333', - }, - ], - }, - }); - - expect(resultString).toEqual(expectedString); - }); - - it('should pass the exact response data from Kubernetes (multi cluster)', async () => { - const clusters: ClusterDetails[] = [ - { - name: 'cluster1', - url: 'http://localhost:9998', - serviceAccountToken: 'token', - authProvider: 'serviceAccount', - skipTLSVerify: true, - }, - { - name: 'cluster2', - url: 'http://localhost:9999', - serviceAccountToken: 'token', - authProvider: 'serviceAccount', - skipTLSVerify: true, - }, - ]; - - const clustersSupplier = buildClustersSupplierWithClusters(clusters); - const req = buildEncodedRequest( - { cluster1: 'token', cluster2: 'token' }, - 'api', - ); - - const apiResponse1 = { - kind: 'APIVersions', - versions: ['v1'], - serverAddressByClientCIDRs: [ - { - clientCIDR: '0.0.0.0/0', - serverAddress: '192.168.0.1:3333', - }, - ], - }; - - const apiResponse2 = { - kind: 'Status', - apiVersion: 'v1', - metadata: {}, - status: 'Failure', - message: 'Unauthorized', - reason: 'Unauthorized', - code: 401, - }; - - worker.use( - rest.get(`${clusters[0].url}/${req.params.encodedQuery}`, (_, res, ctx) => - res(ctx.status(200), ctx.body(JSON.stringify(apiResponse1))), - ), - rest.get(`${clusters[1].url}/${req.params.encodedQuery}`, (_, res, ctx) => - res(ctx.status(401), ctx.body(JSON.stringify(apiResponse2))), - ), - ); - - const result = await proxy.handleProxyRequest(req, clustersSupplier); - - const resultString = JSON.stringify(result.data); - const expectedString = JSON.stringify({ - cluster1: { - kind: 'APIVersions', - versions: ['v1'], - serverAddressByClientCIDRs: [ - { - clientCIDR: '0.0.0.0/0', - serverAddress: '192.168.0.1:3333', - }, - ], - }, - cluster2: { - kind: 'Status', - apiVersion: 'v1', - metadata: {}, - status: 'Failure', - message: 'Unauthorized', - reason: 'Unauthorized', - code: 401, - }, - }); - - expect(resultString).toEqual(expectedString); + expect(response.status).toHaveBeenCalledWith(200); + expect(response.json).toHaveBeenCalledWith(apiResponse); }); }); diff --git a/plugins/kubernetes-backend/src/service/KubernetesProxy.ts b/plugins/kubernetes-backend/src/service/KubernetesProxy.ts index dea4786820..d1a34cb2cf 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesProxy.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesProxy.ts @@ -19,151 +19,105 @@ import { ForwardedError, InputError, NotFoundError, - stringifyError, } from '@backstage/errors'; import { bufferFromFileOrString, KubeConfig } from '@kubernetes/client-node'; import * as https from 'https'; -import fetch, { RequestInit } from 'node-fetch'; +import fetch, { RequestInit, Response } from 'node-fetch'; import { Logger } from 'winston'; import { ClusterDetails, KubernetesClustersSupplier } from '../types/types'; -import type { Request } from 'express'; +import type { Request as ExpressRequest, RequestHandler } from 'express'; + +/** + * + * @alpha + */ +export const APPLICATION_JSON: string = 'application/json'; + +/** + * + * @alpha + */ +export const HEADER_KUBERNETES_CLUSTER: string = 'X-Kubernetes-Cluster'; const HEADER_CONTENT_TYPE: string = 'Content-Type'; -const APPLICATION_JSON: string = 'application/json'; - -const HEADER_KUBERNETES_CLUSTERS: string = 'X-Kubernetes-Clusters'; - -const ERROR_INTERNAL_SERVER: number = 500; const CLUSTER_USER_NAME: string = 'backstage'; -/** - * - * @alpha - */ -export interface KubernetesProxyResponse { - code: number; - data: any; - cluster?: string; -} - -/** - * - * @alpha - */ -interface KubernetesProxyClusters { - [key: string]: string; -} - /** * * @alpha */ export class KubernetesProxy { + private _clustersSupplier?: KubernetesClustersSupplier; + + static readonly PROXY_PATH: string = '/proxy/:path(*)'; + constructor(protected readonly logger: Logger) {} - public async handleProxyRequest( - req: Request, - clusterSupplier: KubernetesClustersSupplier, - ): Promise { - const requestedClusters = this.getKubernetesRequestedClusters(req); + public proxyRequestHandler: RequestHandler = async (req, res) => { + const requestedCluster = this.getKubernetesRequestedCluster(req); - if (Object.keys(requestedClusters).length < 1) { - this.logger.error(`No clusters found`); - throw new NotFoundError('No clusters found!'); + const clusterDetails = await this.getClusterDetails(requestedCluster); + + const response = await this.makeRequestToCluster(clusterDetails, req); + + const contentType = req.header(HEADER_CONTENT_TYPE) || APPLICATION_JSON; + + const data = contentType.includes(APPLICATION_JSON) + ? await response.json() + : await response.text(); + + res.status(response.status).json(data); + }; + + public get clustersSupplier(): KubernetesClustersSupplier { + if (this._clustersSupplier ? false : this._clustersSupplier ?? true) { + throw new ConflictError("Missing Proxy's Clusters Supplier"); } - const clusterDetails = await this.getClusterDetails( - clusterSupplier, - requestedClusters, - ); - - if (clusterDetails.length < 1) { - this.logger.error(`No clusters found`); - throw new NotFoundError('No clusters found!'); - } - - const responses = await Promise.all( - clusterDetails.map(async clusterDetail => { - const response = await this.makeRequestToCluster(clusterDetail, req); - return response; - }), - ); - - const data: { [key: string]: any } = {}; - const codes: number[] = []; - - responses.forEach(kpr => { - if (kpr.cluster) { - data[kpr.cluster] = kpr.data; - codes.push(kpr.code); - } - }); - - const code = this.getBestResponseCode(codes); - - const res: KubernetesProxyResponse = { - code, - data, - }; - - return res; + return this._clustersSupplier as KubernetesClustersSupplier; } - private getKubernetesRequestedClusters( - req: Request, - ): KubernetesProxyClusters { - const encodedClusters: string = - req.header(HEADER_KUBERNETES_CLUSTERS) ?? ''; + public set clustersSupplier(clustersSupplier) { + this._clustersSupplier = clustersSupplier; + } - if (!encodedClusters) { - return {}; + private getKubernetesRequestedCluster(req: ExpressRequest): string { + const requestedClusterName: string = + req.header(HEADER_KUBERNETES_CLUSTER) ?? ''; + + if (!requestedClusterName) { + this.logger.error(`Malformed ${HEADER_KUBERNETES_CLUSTER} header.`); + throw new InputError(`Malformed ${HEADER_KUBERNETES_CLUSTER} header.`); } - try { - const decodedClusters = Buffer.from(encodedClusters, 'base64').toString(); - const clusters: KubernetesProxyClusters = JSON.parse(decodedClusters); - return clusters; - } catch (e: any) { - this.logger.debug( - `error with encoded cluster header: ${stringifyError(e)}`, - ); - } - return {}; + return requestedClusterName; } private async getClusterDetails( - clusterSupplier: KubernetesClustersSupplier, - requestedClusters: KubernetesProxyClusters, - ): Promise { - const clusters = await clusterSupplier.getClusters(); + requestedCluster: string, + ): Promise { + const clusters = await this.clustersSupplier.getClusters(); - const clusterNames = Object.keys(requestedClusters); + const clusterDetail = clusters.find(cluster => + requestedCluster.includes(cluster.name), + ); - const clusterDetails = clusters.filter(c => clusterNames.includes(c.name)); + if (clusterDetail ? false : clusterDetail ?? true) { + this.logger.error( + `Cluster ${requestedCluster} details not found in config`, + ); - const clusterDetailsAuth = clusterDetails.map(c => { - const cAuth: ClusterDetails = Object.assign(c, { - serviceAccountToken: requestedClusters[c.name], - }); - return cAuth; - }); + throw new NotFoundError("Cluster's detail not found"); + } - return clusterDetailsAuth; + return clusterDetail as ClusterDetails; } private getClusterURI(details: ClusterDetails): string { - const client = this.getKubeConfig(details); - return client.getCurrentCluster()?.server || ''; - } - - private async makeRequestToCluster( - details: ClusterDetails, - req: Request, - ): Promise { - const serverURI = this.getClusterURI(details); + const serverURI = this.getKubeConfig(details)?.getCurrentCluster()?.server; if (!serverURI) { this.logger.error(`Cluster ${details.name} details IP error`); @@ -171,27 +125,26 @@ export class KubernetesProxy { throw new ConflictError('Cluster detail error'); } - const query = decodeURIComponent(req.params.encodedQuery) || ''; - const uri = `${serverURI}/${query}`; + return serverURI; + } - const contentType = req.header(HEADER_CONTENT_TYPE) || APPLICATION_JSON; + private async makeRequestToCluster( + details: ClusterDetails, + req: ExpressRequest, + ): Promise { + const serverURI = this.getClusterURI(details); - return await this.sendClusterRequest( - details, - uri, - req.method, - contentType, - req.body, - ); + const path = decodeURIComponent(req.params.path) || ''; + const uri = `${serverURI}/${path}`; + + return await this.sendClusterRequest(details, uri, req); } private async sendClusterRequest( details: ClusterDetails, uri: string, - method: string, - contentType: string, - body?: any, - ): Promise { + req: ExpressRequest, + ): Promise { const bearerToken = details.serviceAccountToken; if (!bearerToken) { @@ -200,12 +153,11 @@ export class KubernetesProxy { throw new AuthenticationError('Invalid service account token'); } + const { method, headers, body } = req; + const reqData: RequestInit = { method, - headers: { - 'Content-Type': contentType, - Authorization: `Bearer ${bearerToken}`, - }, + headers: headers as { [key: string]: string }, }; if (!details.skipTLSVerify) { @@ -214,6 +166,7 @@ export class KubernetesProxy { reqData.agent = new https.Agent({ ca }); } else { this.logger.error('could not find CA certificate!'); + throw new InputError( 'Invalid CA certificate configured within Backstage', ); @@ -225,23 +178,7 @@ export class KubernetesProxy { } try { - const res = await fetch(uri, reqData); - - let data: string | any; - - if (contentType.includes(APPLICATION_JSON)) { - data = await res.json(); - } else { - data = await res.text(); - } - - const proxyResponse: KubernetesProxyResponse = { - code: res.status, - data, - cluster: details.name, - }; - - return proxyResponse; + return fetch(uri, reqData); } catch (e: any) { throw new ForwardedError(`Cluster ${details.name} request error`, e); } @@ -281,9 +218,4 @@ export class KubernetesProxy { return kubeConfig; } - - private getBestResponseCode(codes: number[]): number { - const sorted = codes.sort(); - return sorted[0] ?? ERROR_INTERNAL_SERVER; - } } diff --git a/yarn.lock b/yarn.lock index ae10e493f5..653eeec7ce 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5973,6 +5973,7 @@ __metadata: "@backstage/plugin-auth-node": "workspace:^" "@backstage/plugin-kubernetes-common": "workspace:^" "@google-cloud/container": ^4.0.0 + "@jest-mock/express": ^2.0.1 "@kubernetes/client-node": 0.17.0 "@types/aws4": ^1.5.1 "@types/express": ^4.17.6 @@ -5990,7 +5991,7 @@ __metadata: luxon: ^3.0.0 morgan: ^1.10.0 msw: ^0.48.0 - node-fetch: ^2.6.0 + node-fetch: ^2.6.7 stream-buffers: ^3.0.2 supertest: ^6.1.3 winston: ^3.2.1 @@ -9250,6 +9251,15 @@ __metadata: languageName: node linkType: hard +"@jest-mock/express@npm:^2.0.1": + version: 2.0.1 + resolution: "@jest-mock/express@npm:2.0.1" + dependencies: + "@types/express": ^4.17.13 + checksum: 999ea0a953b3e911d0b8ecc4cb3b78ac252b3354832db9659be6754094410b10508f1688f3e623ab13fe40c28d89fd5a81699e6acd148dd8128abec4e81f3f14 + languageName: node + linkType: hard + "@jest/console@npm:^29.0.3": version: 29.0.3 resolution: "@jest/console@npm:29.0.3" From b372602d8c55abd3eafe0340b1fbc0c6a0971dd7 Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Date: Tue, 1 Nov 2022 14:39:58 -0500 Subject: [PATCH 43/83] fix: Remove unused type in @backstage/kubernetes-common Signed-off-by: Carlos Esteban Lopez --- .../kubernetes-backend/src/service/KubernetesProxy.test.ts | 4 ++-- plugins/kubernetes-common/api-report.md | 6 ------ plugins/kubernetes-common/src/types.ts | 5 ----- 3 files changed, 2 insertions(+), 13 deletions(-) diff --git a/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts b/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts index adf9357bb3..530cba2573 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts @@ -17,6 +17,8 @@ import 'buffer'; import { getVoidLogger } from '@backstage/backend-common'; import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { NotFoundError } from '@backstage/errors'; +import { getMockReq, getMockRes } from '@jest-mock/express'; import { Request } from 'express'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; @@ -27,8 +29,6 @@ import { HEADER_KUBERNETES_CLUSTER, KubernetesProxy, } from './KubernetesProxy'; -import { NotFoundError } from '@backstage/errors'; -import { getMockReq, getMockRes } from '@jest-mock/express'; describe('KubernetesProxy', () => { let proxy: KubernetesProxy; diff --git a/plugins/kubernetes-common/api-report.md b/plugins/kubernetes-common/api-report.md index c504558b00..8509fa97cc 100644 --- a/plugins/kubernetes-common/api-report.md +++ b/plugins/kubernetes-common/api-report.md @@ -193,12 +193,6 @@ export interface KubernetesFetchError { statusCode?: number; } -// @public (undocumented) -export interface KubernetesProxyClusters { - // (undocumented) - [key: string]: string; -} - // @public (undocumented) export interface KubernetesRequestAuth { // (undocumented) diff --git a/plugins/kubernetes-common/src/types.ts b/plugins/kubernetes-common/src/types.ts index d0bf7757fb..3feddd7f4c 100644 --- a/plugins/kubernetes-common/src/types.ts +++ b/plugins/kubernetes-common/src/types.ts @@ -258,8 +258,3 @@ export interface ClientPodStatus { memory: ClientCurrentResourceUsage; containers: ClientContainerStatus[]; } - -/** @public */ -export interface KubernetesProxyClusters { - [key: string]: string; -} From 718f66f235b86537d2cd29342d9342efbc6739be Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Date: Wed, 9 Nov 2022 16:49:26 -0500 Subject: [PATCH 44/83] fix: Handle skipTLSVerify properly Signed-off-by: Carlos Esteban Lopez --- .../src/service/KubernetesProxy.ts | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/plugins/kubernetes-backend/src/service/KubernetesProxy.ts b/plugins/kubernetes-backend/src/service/KubernetesProxy.ts index d1a34cb2cf..9da0068072 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesProxy.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesProxy.ts @@ -160,17 +160,17 @@ export class KubernetesProxy { headers: headers as { [key: string]: string }, }; - if (!details.skipTLSVerify) { - if (details.caData) { - const ca = bufferFromFileOrString('', details.caData)?.toString() || ''; - reqData.agent = new https.Agent({ ca }); - } else { - this.logger.error('could not find CA certificate!'); + if (details.skipTLSVerify) { + reqData.agent = new https.Agent({ rejectUnauthorized: false }); + } else if (details.caData) { + const ca = bufferFromFileOrString('', details.caData)?.toString() || ''; + reqData.agent = new https.Agent({ ca }); + } else { + this.logger.error('could not find CA certificate!'); - throw new InputError( - 'Invalid CA certificate configured within Backstage', - ); - } + throw new InputError( + 'Invalid CA certificate configured within Backstage', + ); } if (body && Object.keys(body).length > 0) { From 033a717b0abb86781361e23b4bfc8384263e1ef8 Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Date: Wed, 9 Nov 2022 18:43:18 -0500 Subject: [PATCH 45/83] fix: Update test urls to https Signed-off-by: Carlos Esteban Lopez --- .../kubernetes-backend/src/service/KubernetesProxy.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts b/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts index 530cba2573..a72681fc73 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts @@ -85,7 +85,7 @@ describe('KubernetesProxy', () => { const clusters: ClusterDetails[] = [ { name: 'cluster1', - url: 'http://localhost:9999', + url: 'https://localhost:9999', serviceAccountToken: 'token', authProvider: 'serviceAccount', skipTLSVerify: true, @@ -124,7 +124,7 @@ describe('KubernetesProxy', () => { const clusters: ClusterDetails[] = [ { name: 'cluster1', - url: 'http://localhost:9999', + url: 'https://localhost:9999', serviceAccountToken: 'token', authProvider: 'serviceAccount', skipTLSVerify: true, From a05aa6cc69dbd3dec86e24ae63a43e08179c4af4 Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Jaramillo Date: Tue, 15 Nov 2022 12:16:00 -0500 Subject: [PATCH 46/83] Update plugins/kubernetes-backend/src/service/KubernetesProxy.ts Co-authored-by: Jamie Klassen Signed-off-by: Carlos Esteban Lopez Jaramillo --- plugins/kubernetes-backend/src/service/KubernetesProxy.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/plugins/kubernetes-backend/src/service/KubernetesProxy.ts b/plugins/kubernetes-backend/src/service/KubernetesProxy.ts index 9da0068072..b41c421673 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesProxy.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesProxy.ts @@ -145,14 +145,6 @@ export class KubernetesProxy { uri: string, req: ExpressRequest, ): Promise { - const bearerToken = details.serviceAccountToken; - - if (!bearerToken) { - this.logger.error('Invalid service account token'); - - throw new AuthenticationError('Invalid service account token'); - } - const { method, headers, body } = req; const reqData: RequestInit = { From e4af45dc470674260f4963ec4c9f41497ebead01 Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Jaramillo Date: Tue, 15 Nov 2022 12:17:44 -0500 Subject: [PATCH 47/83] Update plugins/kubernetes-backend/src/service/KubernetesProxy.ts Co-authored-by: Jamie Klassen Signed-off-by: Carlos Esteban Lopez Jaramillo --- plugins/kubernetes-backend/src/service/KubernetesProxy.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/plugins/kubernetes-backend/src/service/KubernetesProxy.ts b/plugins/kubernetes-backend/src/service/KubernetesProxy.ts index b41c421673..6cd6bd507e 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesProxy.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesProxy.ts @@ -157,12 +157,6 @@ export class KubernetesProxy { } else if (details.caData) { const ca = bufferFromFileOrString('', details.caData)?.toString() || ''; reqData.agent = new https.Agent({ ca }); - } else { - this.logger.error('could not find CA certificate!'); - - throw new InputError( - 'Invalid CA certificate configured within Backstage', - ); } if (body && Object.keys(body).length > 0) { From d936b2fecad0a42834f85e61c0e2ce65fe7bb33f Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Jaramillo Date: Tue, 15 Nov 2022 12:19:35 -0500 Subject: [PATCH 48/83] Update plugins/kubernetes-backend/src/service/KubernetesProxy.ts Co-authored-by: Jamie Klassen Signed-off-by: Carlos Esteban Lopez Jaramillo --- .../src/service/KubernetesProxy.ts | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/plugins/kubernetes-backend/src/service/KubernetesProxy.ts b/plugins/kubernetes-backend/src/service/KubernetesProxy.ts index 6cd6bd507e..83e460f6e6 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesProxy.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesProxy.ts @@ -116,23 +116,11 @@ export class KubernetesProxy { return clusterDetail as ClusterDetails; } - private getClusterURI(details: ClusterDetails): string { - const serverURI = this.getKubeConfig(details)?.getCurrentCluster()?.server; - - if (!serverURI) { - this.logger.error(`Cluster ${details.name} details IP error`); - - throw new ConflictError('Cluster detail error'); - } - - return serverURI; - } - private async makeRequestToCluster( details: ClusterDetails, req: ExpressRequest, ): Promise { - const serverURI = this.getClusterURI(details); + const serverURI = details.url; const path = decodeURIComponent(req.params.path) || ''; const uri = `${serverURI}/${path}`; From edc9ed6952481fea82f9c5e7bf8c16f97df633c7 Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Jaramillo Date: Tue, 15 Nov 2022 12:21:09 -0500 Subject: [PATCH 49/83] Update plugins/kubernetes-backend/src/service/KubernetesProxy.ts Co-authored-by: Jamie Klassen Signed-off-by: Carlos Esteban Lopez Jaramillo --- .../src/service/KubernetesProxy.ts | 35 ------------------- 1 file changed, 35 deletions(-) diff --git a/plugins/kubernetes-backend/src/service/KubernetesProxy.ts b/plugins/kubernetes-backend/src/service/KubernetesProxy.ts index 83e460f6e6..416b3a047b 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesProxy.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesProxy.ts @@ -158,38 +158,3 @@ export class KubernetesProxy { } } - private getKubeConfig(clusterDetails: ClusterDetails): KubeConfig { - const cluster = { - name: clusterDetails.name, - server: clusterDetails.url, - skipTLSVerify: clusterDetails.skipTLSVerify, - caData: clusterDetails.caData, - }; - - const user = { - name: CLUSTER_USER_NAME, - token: clusterDetails.serviceAccountToken, - }; - - const context = { - name: clusterDetails.name, - user: user.name, - cluster: cluster.name, - }; - - const kubeConfig = new KubeConfig(); - - if (clusterDetails.serviceAccountToken) { - kubeConfig.loadFromOptions({ - clusters: [cluster], - users: [user], - contexts: [context], - currentContext: context.name, - }); - } else { - kubeConfig.loadFromDefault(); - } - - return kubeConfig; - } -} From cead48f628a5c476acea0f48b94fa04d059dd289 Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Jaramillo Date: Tue, 15 Nov 2022 12:22:02 -0500 Subject: [PATCH 50/83] Update plugins/kubernetes-backend/src/service/KubernetesProxy.ts Co-authored-by: Jamie Klassen Signed-off-by: Carlos Esteban Lopez Jaramillo --- plugins/kubernetes-backend/src/service/KubernetesProxy.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/plugins/kubernetes-backend/src/service/KubernetesProxy.ts b/plugins/kubernetes-backend/src/service/KubernetesProxy.ts index 416b3a047b..92f3c0ea6c 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesProxy.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesProxy.ts @@ -63,13 +63,9 @@ export class KubernetesProxy { const response = await this.makeRequestToCluster(clusterDetails, req); - const contentType = req.header(HEADER_CONTENT_TYPE) || APPLICATION_JSON; + const data = await response.text(); - const data = contentType.includes(APPLICATION_JSON) - ? await response.json() - : await response.text(); - - res.status(response.status).json(data); + res.status(response.status).send(data); }; public get clustersSupplier(): KubernetesClustersSupplier { From 5f0b3a1d4f551acd587b1603a4c0598b057fb6f3 Mon Sep 17 00:00:00 2001 From: Jamie Klassen Date: Thu, 17 Nov 2022 16:55:51 -0500 Subject: [PATCH 51/83] refactor to use http-proxy-middleware Signed-off-by: Jamie Klassen --- plugins/kubernetes-backend/api-report.md | 22 +-- plugins/kubernetes-backend/package.json | 2 + .../src/service/KubernetesBuilder.ts | 30 ++-- .../src/service/KubernetesProxy.test.ts | 91 +++-------- .../src/service/KubernetesProxy.ts | 154 +++++++----------- yarn.lock | 4 +- 6 files changed, 115 insertions(+), 188 deletions(-) diff --git a/plugins/kubernetes-backend/api-report.md b/plugins/kubernetes-backend/api-report.md index 827ec5e74c..6e0c253f79 100644 --- a/plugins/kubernetes-backend/api-report.md +++ b/plugins/kubernetes-backend/api-report.md @@ -22,7 +22,7 @@ import { Logger } from 'winston'; import { Metrics } from '@kubernetes/client-node'; import type { ObjectsByEntityResponse } from '@backstage/plugin-kubernetes-common'; import { PluginEndpointDiscovery } from '@backstage/backend-common'; -import type { RequestHandler } from 'express'; +import { RequestHandler } from 'http-proxy-middleware'; import { TokenCredential } from '@azure/identity'; // @alpha (undocumented) @@ -195,12 +195,16 @@ export class KubernetesBuilder { options: KubernetesObjectsProviderOptions, ): KubernetesObjectsProvider; // (undocumented) - protected buildProxy(): KubernetesProxy; + protected buildProxy( + logger: Logger, + clusterSupplier: KubernetesClustersSupplier, + ): KubernetesProxy; // (undocumented) protected buildRouter( objectsProvider: KubernetesObjectsProvider, clusterSupplier: KubernetesClustersSupplier, catalogApi: CatalogApi, + proxy: KubernetesProxy, ): express.Router; // (undocumented) protected buildServiceLocator( @@ -226,7 +230,10 @@ export class KubernetesBuilder { // (undocumented) protected getObjectTypesToFetch(): ObjectToFetch[] | undefined; // (undocumented) - protected getProxy(): KubernetesProxy; + protected getProxy( + logger: Logger, + clusterSupplier: KubernetesClustersSupplier, + ): KubernetesProxy; // (undocumented) protected getServiceLocator(): KubernetesServiceLocator; // (undocumented) @@ -348,14 +355,7 @@ export type KubernetesObjectTypes = // @alpha (undocumented) export class KubernetesProxy { - constructor(logger: Logger); - // (undocumented) - get clustersSupplier(): KubernetesClustersSupplier; - set clustersSupplier(clustersSupplier: KubernetesClustersSupplier); - // (undocumented) - protected readonly logger: Logger; - // (undocumented) - static readonly PROXY_PATH: string; + constructor(logger: Logger, clusterSupplier: KubernetesClustersSupplier); // (undocumented) proxyRequestHandler: RequestHandler; } diff --git a/plugins/kubernetes-backend/package.json b/plugins/kubernetes-backend/package.json index d5ab468790..9c6cfd0563 100644 --- a/plugins/kubernetes-backend/package.json +++ b/plugins/kubernetes-backend/package.json @@ -56,6 +56,7 @@ "express-promise-router": "^4.1.0", "fs-extra": "10.1.0", "helmet": "^6.0.0", + "http-proxy-middleware": "^2.0.6", "lodash": "^4.17.21", "luxon": "^3.0.0", "morgan": "^1.10.0", @@ -67,6 +68,7 @@ "devDependencies": { "@backstage/cli": "workspace:^", "@types/aws4": "^1.5.1", + "@types/http-proxy-middleware": "^0.19.3", "aws-sdk-mock": "^5.2.1", "msw": "^0.48.0", "supertest": "^6.1.3" diff --git a/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts b/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts index 3ac27decc8..a5e67ebe2a 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts @@ -108,11 +108,9 @@ export class KubernetesBuilder { const fetcher = this.getFetcher(); - const proxy = this.getProxy(); - const clusterSupplier = this.getClusterSupplier(); - proxy.clustersSupplier = clusterSupplier; + const proxy = this.getProxy(logger, clusterSupplier); const serviceLocator = this.getServiceLocator(); @@ -128,6 +126,7 @@ export class KubernetesBuilder { objectsProvider, clusterSupplier, this.env.catalogApi, + proxy, ); return { @@ -252,8 +251,11 @@ export class KubernetesBuilder { throw new Error('not implemented'); } - protected buildProxy(): KubernetesProxy { - this.proxy = new KubernetesProxy(this.env.logger); + protected buildProxy( + logger: Logger, + clusterSupplier: KubernetesClustersSupplier, + ): KubernetesProxy { + this.proxy = new KubernetesProxy(logger, clusterSupplier); return this.proxy; } @@ -261,13 +263,12 @@ export class KubernetesBuilder { objectsProvider: KubernetesObjectsProvider, clusterSupplier: KubernetesClustersSupplier, catalogApi: CatalogApi, + proxy: KubernetesProxy, ): express.Router { const logger = this.env.logger; const router = Router(); router.use(express.json()); - const proxy = this.getProxy(); - // @deprecated router.post('/services/:serviceId', async (req, res) => { const serviceId = req.params.serviceId; @@ -298,13 +299,7 @@ export class KubernetesBuilder { }); }); - if (typeof proxy?.proxyRequestHandler === 'function') { - router.get(KubernetesProxy.PROXY_PATH, proxy.proxyRequestHandler); - router.post(KubernetesProxy.PROXY_PATH, proxy.proxyRequestHandler); - router.put(KubernetesProxy.PROXY_PATH, proxy.proxyRequestHandler); - router.patch(KubernetesProxy.PROXY_PATH, proxy.proxyRequestHandler); - router.delete(KubernetesProxy.PROXY_PATH, proxy.proxyRequestHandler); - } + router.use('/proxy', proxy.proxyRequestHandler); addResourceRoutesToRouter(router, catalogApi, objectsProvider); @@ -384,7 +379,10 @@ export class KubernetesBuilder { return objectTypesToFetch; } - protected getProxy() { - return this.proxy ?? this.buildProxy(); + protected getProxy( + logger: Logger, + clusterSupplier: KubernetesClustersSupplier, + ) { + return this.proxy ?? this.buildProxy(logger, clusterSupplier); } } diff --git a/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts b/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts index a72681fc73..5d4eaa795b 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts @@ -16,12 +16,14 @@ import 'buffer'; import { getVoidLogger } from '@backstage/backend-common'; -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; import { NotFoundError } from '@backstage/errors'; import { getMockReq, getMockRes } from '@jest-mock/express'; -import { Request } from 'express'; +import type { Request } from 'express'; +import express from 'express'; +import request from 'supertest'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; +import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; import { ClusterDetails, KubernetesClustersSupplier } from '../types/types'; import { @@ -33,6 +35,7 @@ import { describe('KubernetesProxy', () => { let proxy: KubernetesProxy; const worker = setupServer(); + setupRequestMockHandlers(worker); const buildMockRequest = (clusterName: any, path: string): Request => { @@ -58,20 +61,17 @@ describe('KubernetesProxy', () => { return req; }; - const buildClustersSupplierWithClusters = ( - clusters: ClusterDetails[], - ): KubernetesClustersSupplier => ({ - getClusters: async () => { - return clusters; - }, - }); + const clusterSupplier: jest.Mocked = { + getClusters: jest.fn(), + }; beforeEach(() => { - proxy = new KubernetesProxy(getVoidLogger()); + jest.resetAllMocks(); + proxy = new KubernetesProxy(getVoidLogger(), clusterSupplier); }); it('should return a ERROR_NOT_FOUND if no clusters are found', async () => { - proxy.clustersSupplier = buildClustersSupplierWithClusters([]); + clusterSupplier.getClusters.mockResolvedValue([]); const req = buildMockRequest('test', 'api'); const { res, next } = getMockRes(); @@ -81,22 +81,7 @@ describe('KubernetesProxy', () => { ); }); - it('should match the response code of the Kubernetes response', async () => { - const clusters: ClusterDetails[] = [ - { - name: 'cluster1', - url: 'https://localhost:9999', - serviceAccountToken: 'token', - authProvider: 'serviceAccount', - skipTLSVerify: true, - }, - ]; - - proxy.clustersSupplier = buildClustersSupplierWithClusters(clusters); - - const req = buildMockRequest('cluster1', 'api'); - const { res: response, next } = getMockRes(); - + it('should pass the exact response from Kubernetes', async () => { const apiResponse = { kind: 'APIVersions', versions: ['v1'], @@ -108,54 +93,28 @@ describe('KubernetesProxy', () => { ], }; - worker.use( - rest.get(`${clusters[0].url}/${req.params.path}`, (_, res, ctx) => - res(ctx.status(299), ctx.body(JSON.stringify(apiResponse))), - ), - ); - - await proxy.proxyRequestHandler(req, response, next); - - expect(response.status).toHaveBeenCalledWith(299); - expect(response.json).toHaveBeenCalledWith(apiResponse); - }); - - it('should pass the exact response data from Kubernetes', async () => { - const clusters: ClusterDetails[] = [ + clusterSupplier.getClusters.mockResolvedValue([ { name: 'cluster1', url: 'https://localhost:9999', - serviceAccountToken: 'token', + serviceAccountToken: '', authProvider: 'serviceAccount', - skipTLSVerify: true, }, - ]; - - proxy.clustersSupplier = buildClustersSupplierWithClusters(clusters); - - const req = buildMockRequest('cluster1', 'api'); - const { res: response, next } = getMockRes(); - - const apiResponse = { - kind: 'APIVersions', - versions: ['v1'], - serverAddressByClientCIDRs: [ - { - clientCIDR: '0.0.0.0/0', - serverAddress: '192.168.0.1:3333', - }, - ], - }; - + ] as ClusterDetails[]); + const app = express().use('/mountpath', proxy.proxyRequestHandler); + const requestPromise = request(app) + .get('/mountpath/api') + .set(HEADER_KUBERNETES_CLUSTER, 'cluster1'); worker.use( - rest.get(`${clusters[0].url}/${req.params.path}`, (_, res, ctx) => - res(ctx.status(200), ctx.body(JSON.stringify(apiResponse))), + rest.get('https://localhost:9999/api', (_, res, ctx) => + res(ctx.status(299), ctx.json(apiResponse)), ), + rest.all(requestPromise.url, (req, _res, _ctx) => req.passthrough()), ); - await proxy.proxyRequestHandler(req, response, next); + const response = await requestPromise; - expect(response.status).toHaveBeenCalledWith(200); - expect(response.json).toHaveBeenCalledWith(apiResponse); + expect(response.status).toEqual(299); + expect(response.body).toStrictEqual(apiResponse); }); }); diff --git a/plugins/kubernetes-backend/src/service/KubernetesProxy.ts b/plugins/kubernetes-backend/src/service/KubernetesProxy.ts index 92f3c0ea6c..7cc3a97416 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesProxy.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesProxy.ts @@ -13,21 +13,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { - AuthenticationError, - ConflictError, - ForwardedError, - InputError, - NotFoundError, -} from '@backstage/errors'; -import { bufferFromFileOrString, KubeConfig } from '@kubernetes/client-node'; -import * as https from 'https'; -import fetch, { RequestInit, Response } from 'node-fetch'; +import { ForwardedError, InputError, NotFoundError } from '@backstage/errors'; +import { bufferFromFileOrString } from '@kubernetes/client-node'; import { Logger } from 'winston'; +import { ErrorResponseBody, serializeError } from '@backstage/errors'; import { ClusterDetails, KubernetesClustersSupplier } from '../types/types'; -import type { Request as ExpressRequest, RequestHandler } from 'express'; +import type { Request } from 'express'; +import { + RequestHandler, + Options, + createProxyMiddleware, +} from 'http-proxy-middleware'; /** * @@ -41,52 +39,66 @@ export const APPLICATION_JSON: string = 'application/json'; */ export const HEADER_KUBERNETES_CLUSTER: string = 'X-Kubernetes-Cluster'; -const HEADER_CONTENT_TYPE: string = 'Content-Type'; - -const CLUSTER_USER_NAME: string = 'backstage'; - /** * * @alpha */ export class KubernetesProxy { - private _clustersSupplier?: KubernetesClustersSupplier; + constructor( + private readonly logger: Logger, + private readonly clusterSupplier: KubernetesClustersSupplier, + ) {} - static readonly PROXY_PATH: string = '/proxy/:path(*)'; - - constructor(protected readonly logger: Logger) {} - - public proxyRequestHandler: RequestHandler = async (req, res) => { + public proxyRequestHandler: RequestHandler = async (req, res, next) => { const requestedCluster = this.getKubernetesRequestedCluster(req); const clusterDetails = await this.getClusterDetails(requestedCluster); - const response = await this.makeRequestToCluster(clusterDetails, req); + const clusterUrl = new URL(clusterDetails.url); + const options = { + logProvider: () => this.logger, + secure: !clusterDetails.skipTLSVerify, + target: { + protocol: clusterUrl.protocol, + host: clusterUrl.hostname, + port: clusterUrl.port, + ca: bufferFromFileOrString('', clusterDetails.caData)?.toString(), + }, + pathRewrite: { [`^${req.baseUrl}`]: '' }, + onError: (error: Error) => { + const wrappedError = new ForwardedError( + `Cluster '${requestedCluster}' request error`, + error, + ); - const data = await response.text(); + this.logger.error(wrappedError); - res.status(response.status).send(data); + const body: ErrorResponseBody = { + error: serializeError(wrappedError, { + includeStack: process.env.NODE_ENV === 'development', + }), + request: { method: req.method, url: req.originalUrl }, + response: { statusCode: 500 }, + }; + + res.status(500).json(body); + }, + } as Options; + + // Probably too risky without permissions protecting this endpoint + // if (clusterDetails.serviceAccountToken) { + // options.headers = { + // Authorization: `Bearer ${clusterDetails.serviceAccountToken}`, + // }; + // } + createProxyMiddleware(options)(req, res, next); }; - public get clustersSupplier(): KubernetesClustersSupplier { - if (this._clustersSupplier ? false : this._clustersSupplier ?? true) { - throw new ConflictError("Missing Proxy's Clusters Supplier"); - } - - return this._clustersSupplier as KubernetesClustersSupplier; - } - - public set clustersSupplier(clustersSupplier) { - this._clustersSupplier = clustersSupplier; - } - - private getKubernetesRequestedCluster(req: ExpressRequest): string { - const requestedClusterName: string = - req.header(HEADER_KUBERNETES_CLUSTER) ?? ''; + private getKubernetesRequestedCluster(req: Request): string { + const requestedClusterName = req.header(HEADER_KUBERNETES_CLUSTER); if (!requestedClusterName) { - this.logger.error(`Malformed ${HEADER_KUBERNETES_CLUSTER} header.`); - throw new InputError(`Malformed ${HEADER_KUBERNETES_CLUSTER} header.`); + throw new InputError(`Missing '${HEADER_KUBERNETES_CLUSTER}' header.`); } return requestedClusterName; @@ -95,62 +107,16 @@ export class KubernetesProxy { private async getClusterDetails( requestedCluster: string, ): Promise { - const clusters = await this.clustersSupplier.getClusters(); + const clusters = await this.clusterSupplier.getClusters(); - const clusterDetail = clusters.find(cluster => - requestedCluster.includes(cluster.name), + const clusterDetail = clusters.find( + cluster => cluster.name === requestedCluster, ); - if (clusterDetail ? false : clusterDetail ?? true) { - this.logger.error( - `Cluster ${requestedCluster} details not found in config`, - ); - - throw new NotFoundError("Cluster's detail not found"); + if (!clusterDetail) { + throw new NotFoundError(`Cluster '${requestedCluster}' not found`); } - return clusterDetail as ClusterDetails; + return clusterDetail; } - - private async makeRequestToCluster( - details: ClusterDetails, - req: ExpressRequest, - ): Promise { - const serverURI = details.url; - - const path = decodeURIComponent(req.params.path) || ''; - const uri = `${serverURI}/${path}`; - - return await this.sendClusterRequest(details, uri, req); - } - - private async sendClusterRequest( - details: ClusterDetails, - uri: string, - req: ExpressRequest, - ): Promise { - const { method, headers, body } = req; - - const reqData: RequestInit = { - method, - headers: headers as { [key: string]: string }, - }; - - if (details.skipTLSVerify) { - reqData.agent = new https.Agent({ rejectUnauthorized: false }); - } else if (details.caData) { - const ca = bufferFromFileOrString('', details.caData)?.toString() || ''; - reqData.agent = new https.Agent({ ca }); - } - - if (body && Object.keys(body).length > 0) { - reqData.body = JSON.stringify(body); - } - - try { - return fetch(uri, reqData); - } catch (e: any) { - throw new ForwardedError(`Cluster ${details.name} request error`, e); - } - } - +} diff --git a/yarn.lock b/yarn.lock index 653eeec7ce..b049053f9e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5977,6 +5977,7 @@ __metadata: "@kubernetes/client-node": 0.17.0 "@types/aws4": ^1.5.1 "@types/express": ^4.17.6 + "@types/http-proxy-middleware": ^0.19.3 "@types/luxon": ^3.0.0 aws-sdk: ^2.840.0 aws-sdk-mock: ^5.2.1 @@ -5987,6 +5988,7 @@ __metadata: express-promise-router: ^4.1.0 fs-extra: 10.1.0 helmet: ^6.0.0 + http-proxy-middleware: ^2.0.6 lodash: ^4.17.21 luxon: ^3.0.0 morgan: ^1.10.0 @@ -23361,7 +23363,7 @@ __metadata: languageName: node linkType: hard -"http-proxy-middleware@npm:^2.0.0, http-proxy-middleware@npm:^2.0.3": +"http-proxy-middleware@npm:^2.0.0, http-proxy-middleware@npm:^2.0.3, http-proxy-middleware@npm:^2.0.6": version: 2.0.6 resolution: "http-proxy-middleware@npm:2.0.6" dependencies: From d050ff1b6d2c59c02fc96e7339a5a881eb1fa093 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Fri, 18 Nov 2022 10:16:26 +0100 Subject: [PATCH 52/83] sort out the index files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- plugins/kubernetes-backend/src/index.ts | 20 +++------------- .../src/kubernetes-auth-translator/index.ts | 24 +++++++++++++++++++ .../kubernetes-backend/src/service/index.ts | 21 ++++++++++++++++ plugins/kubernetes-backend/src/types/index.ts | 17 +++++++++++++ 4 files changed, 65 insertions(+), 17 deletions(-) create mode 100644 plugins/kubernetes-backend/src/kubernetes-auth-translator/index.ts create mode 100644 plugins/kubernetes-backend/src/service/index.ts create mode 100644 plugins/kubernetes-backend/src/types/index.ts diff --git a/plugins/kubernetes-backend/src/index.ts b/plugins/kubernetes-backend/src/index.ts index fba5c4a151..67aefbd974 100644 --- a/plugins/kubernetes-backend/src/index.ts +++ b/plugins/kubernetes-backend/src/index.ts @@ -20,20 +20,6 @@ * @packageDocumentation */ -export * from './kubernetes-auth-translator/AwsIamKubernetesAuthTranslator'; -export * from './kubernetes-auth-translator/AzureIdentityKubernetesAuthTranslator'; -export * from './kubernetes-auth-translator/GoogleKubernetesAuthTranslator'; -export * from './kubernetes-auth-translator/GoogleServiceAccountAuthProvider'; -export * from './kubernetes-auth-translator/KubernetesAuthTranslatorGenerator'; -export * from './kubernetes-auth-translator/NoopKubernetesAuthTranslator'; -export * from './kubernetes-auth-translator/OidcKubernetesAuthTranslator'; -export * from './kubernetes-auth-translator/types'; - -export * from './service/router'; -export * from './service/KubernetesBuilder'; -export * from './service/KubernetesClientProvider'; -export * from './service/KubernetesProxy'; - -export * from './types/types'; - -export { DEFAULT_OBJECTS } from './service/KubernetesFanOutHandler'; +export * from './kubernetes-auth-translator'; +export * from './service'; +export * from './types'; diff --git a/plugins/kubernetes-backend/src/kubernetes-auth-translator/index.ts b/plugins/kubernetes-backend/src/kubernetes-auth-translator/index.ts new file mode 100644 index 0000000000..19f6dd80eb --- /dev/null +++ b/plugins/kubernetes-backend/src/kubernetes-auth-translator/index.ts @@ -0,0 +1,24 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './AwsIamKubernetesAuthTranslator'; +export * from './AzureIdentityKubernetesAuthTranslator'; +export * from './GoogleKubernetesAuthTranslator'; +export * from './GoogleServiceAccountAuthProvider'; +export * from './KubernetesAuthTranslatorGenerator'; +export * from './NoopKubernetesAuthTranslator'; +export * from './OidcKubernetesAuthTranslator'; +export * from './types'; diff --git a/plugins/kubernetes-backend/src/service/index.ts b/plugins/kubernetes-backend/src/service/index.ts new file mode 100644 index 0000000000..2b7d576b5c --- /dev/null +++ b/plugins/kubernetes-backend/src/service/index.ts @@ -0,0 +1,21 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './KubernetesBuilder'; +export * from './KubernetesClientProvider'; +export { DEFAULT_OBJECTS } from './KubernetesFanOutHandler'; +export * from './KubernetesProxy'; +export * from './router'; diff --git a/plugins/kubernetes-backend/src/types/index.ts b/plugins/kubernetes-backend/src/types/index.ts new file mode 100644 index 0000000000..db229eae34 --- /dev/null +++ b/plugins/kubernetes-backend/src/types/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './types'; From e4aca04d5c6b866a9cfc67c07f5ddacd05e271ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Fri, 18 Nov 2022 11:54:47 +0100 Subject: [PATCH 53/83] export as a regular express router MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- plugins/kubernetes-backend/api-report.md | 9 ++--- .../src/service/KubernetesProxy.ts | 35 ++++++++++--------- .../kubernetes-backend/src/service/index.ts | 2 +- 3 files changed, 22 insertions(+), 24 deletions(-) diff --git a/plugins/kubernetes-backend/api-report.md b/plugins/kubernetes-backend/api-report.md index 6e0c253f79..6fd5675a8d 100644 --- a/plugins/kubernetes-backend/api-report.md +++ b/plugins/kubernetes-backend/api-report.md @@ -22,12 +22,9 @@ import { Logger } from 'winston'; import { Metrics } from '@kubernetes/client-node'; import type { ObjectsByEntityResponse } from '@backstage/plugin-kubernetes-common'; import { PluginEndpointDiscovery } from '@backstage/backend-common'; -import { RequestHandler } from 'http-proxy-middleware'; +import type { RequestHandler } from 'express'; import { TokenCredential } from '@azure/identity'; -// @alpha (undocumented) -export const APPLICATION_JSON: string; - // @alpha (undocumented) export interface AWSClusterDetails extends ClusterDetails { // (undocumented) @@ -146,7 +143,7 @@ export class GoogleServiceAccountAuthTranslator ): Promise; } -// @alpha (undocumented) +// @alpha export const HEADER_KUBERNETES_CLUSTER: string; // @alpha (undocumented) @@ -353,7 +350,7 @@ export type KubernetesObjectTypes = | 'statefulsets' | 'daemonsets'; -// @alpha (undocumented) +// @alpha export class KubernetesProxy { constructor(logger: Logger, clusterSupplier: KubernetesClustersSupplier); // (undocumented) diff --git a/plugins/kubernetes-backend/src/service/KubernetesProxy.ts b/plugins/kubernetes-backend/src/service/KubernetesProxy.ts index 7cc3a97416..ace07247b1 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesProxy.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesProxy.ts @@ -13,33 +13,34 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { ForwardedError, InputError, NotFoundError } from '@backstage/errors'; -import { bufferFromFileOrString } from '@kubernetes/client-node'; -import { Logger } from 'winston'; -import { ErrorResponseBody, serializeError } from '@backstage/errors'; +import { + ErrorResponseBody, + ForwardedError, + InputError, + NotFoundError, + serializeError, +} from '@backstage/errors'; +import { bufferFromFileOrString } from '@kubernetes/client-node'; +import type { Request, RequestHandler } from 'express'; +import { + createProxyMiddleware, + Options as ProxyMiddlewareOptions, +} from 'http-proxy-middleware'; +import { Logger } from 'winston'; import { ClusterDetails, KubernetesClustersSupplier } from '../types/types'; -import type { Request } from 'express'; -import { - RequestHandler, - Options, - createProxyMiddleware, -} from 'http-proxy-middleware'; - -/** - * - * @alpha - */ export const APPLICATION_JSON: string = 'application/json'; /** + * The header that is used to specify the cluster name. * * @alpha */ export const HEADER_KUBERNETES_CLUSTER: string = 'X-Kubernetes-Cluster'; /** + * A proxy that routes requests to the Kubernetes API. * * @alpha */ @@ -55,7 +56,7 @@ export class KubernetesProxy { const clusterDetails = await this.getClusterDetails(requestedCluster); const clusterUrl = new URL(clusterDetails.url); - const options = { + const options: ProxyMiddlewareOptions = { logProvider: () => this.logger, secure: !clusterDetails.skipTLSVerify, target: { @@ -83,7 +84,7 @@ export class KubernetesProxy { res.status(500).json(body); }, - } as Options; + }; // Probably too risky without permissions protecting this endpoint // if (clusterDetails.serviceAccountToken) { diff --git a/plugins/kubernetes-backend/src/service/index.ts b/plugins/kubernetes-backend/src/service/index.ts index 2b7d576b5c..70ff530bee 100644 --- a/plugins/kubernetes-backend/src/service/index.ts +++ b/plugins/kubernetes-backend/src/service/index.ts @@ -17,5 +17,5 @@ export * from './KubernetesBuilder'; export * from './KubernetesClientProvider'; export { DEFAULT_OBJECTS } from './KubernetesFanOutHandler'; -export * from './KubernetesProxy'; +export { HEADER_KUBERNETES_CLUSTER, KubernetesProxy } from './KubernetesProxy'; export * from './router'; From 2a1eb5549e0a46d9888d0a5c37c21ca5bf061a1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Fri, 18 Nov 2022 15:03:16 +0100 Subject: [PATCH 54/83] memoize middlewares so we don't churn resources excessively MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- plugins/kubernetes-backend/api-report.md | 2 +- .../src/service/KubernetesBuilder.ts | 2 +- .../src/service/KubernetesProxy.test.ts | 7 +- .../src/service/KubernetesProxy.ts | 135 +++++++++--------- 4 files changed, 76 insertions(+), 70 deletions(-) diff --git a/plugins/kubernetes-backend/api-report.md b/plugins/kubernetes-backend/api-report.md index 6fd5675a8d..b88b3f2a02 100644 --- a/plugins/kubernetes-backend/api-report.md +++ b/plugins/kubernetes-backend/api-report.md @@ -354,7 +354,7 @@ export type KubernetesObjectTypes = export class KubernetesProxy { constructor(logger: Logger, clusterSupplier: KubernetesClustersSupplier); // (undocumented) - proxyRequestHandler: RequestHandler; + createRequestHandler(): RequestHandler; } // @alpha diff --git a/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts b/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts index a5e67ebe2a..c8ff98f592 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts @@ -299,7 +299,7 @@ export class KubernetesBuilder { }); }); - router.use('/proxy', proxy.proxyRequestHandler); + router.use('/proxy', proxy.createRequestHandler()); addResourceRoutesToRouter(router, catalogApi, objectsProvider); diff --git a/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts b/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts index 5d4eaa795b..4254bb33da 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts @@ -13,8 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import 'buffer'; +import 'buffer'; import { getVoidLogger } from '@backstage/backend-common'; import { NotFoundError } from '@backstage/errors'; import { getMockReq, getMockRes } from '@jest-mock/express'; @@ -24,7 +24,6 @@ import request from 'supertest'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; - import { ClusterDetails, KubernetesClustersSupplier } from '../types/types'; import { APPLICATION_JSON, @@ -76,7 +75,7 @@ describe('KubernetesProxy', () => { const req = buildMockRequest('test', 'api'); const { res, next } = getMockRes(); - await expect(proxy.proxyRequestHandler(req, res, next)).rejects.toThrow( + await expect(proxy.createRequestHandler()(req, res, next)).rejects.toThrow( NotFoundError, ); }); @@ -101,7 +100,7 @@ describe('KubernetesProxy', () => { authProvider: 'serviceAccount', }, ] as ClusterDetails[]); - const app = express().use('/mountpath', proxy.proxyRequestHandler); + const app = express().use('/mountpath', proxy.createRequestHandler()); const requestPromise = request(app) .get('/mountpath/api') .set(HEADER_KUBERNETES_CLUSTER, 'cluster1'); diff --git a/plugins/kubernetes-backend/src/service/KubernetesProxy.ts b/plugins/kubernetes-backend/src/service/KubernetesProxy.ts index ace07247b1..9d88d2ab84 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesProxy.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesProxy.ts @@ -23,10 +23,7 @@ import { } from '@backstage/errors'; import { bufferFromFileOrString } from '@kubernetes/client-node'; import type { Request, RequestHandler } from 'express'; -import { - createProxyMiddleware, - Options as ProxyMiddlewareOptions, -} from 'http-proxy-middleware'; +import { createProxyMiddleware } from 'http-proxy-middleware'; import { Logger } from 'winston'; import { ClusterDetails, KubernetesClustersSupplier } from '../types/types'; @@ -45,79 +42,89 @@ export const HEADER_KUBERNETES_CLUSTER: string = 'X-Kubernetes-Cluster'; * @alpha */ export class KubernetesProxy { + private readonly middlewareForClusterName = new Map(); + constructor( private readonly logger: Logger, private readonly clusterSupplier: KubernetesClustersSupplier, ) {} - public proxyRequestHandler: RequestHandler = async (req, res, next) => { - const requestedCluster = this.getKubernetesRequestedCluster(req); - - const clusterDetails = await this.getClusterDetails(requestedCluster); - - const clusterUrl = new URL(clusterDetails.url); - const options: ProxyMiddlewareOptions = { - logProvider: () => this.logger, - secure: !clusterDetails.skipTLSVerify, - target: { - protocol: clusterUrl.protocol, - host: clusterUrl.hostname, - port: clusterUrl.port, - ca: bufferFromFileOrString('', clusterDetails.caData)?.toString(), - }, - pathRewrite: { [`^${req.baseUrl}`]: '' }, - onError: (error: Error) => { - const wrappedError = new ForwardedError( - `Cluster '${requestedCluster}' request error`, - error, - ); - - this.logger.error(wrappedError); - - const body: ErrorResponseBody = { - error: serializeError(wrappedError, { - includeStack: process.env.NODE_ENV === 'development', - }), - request: { method: req.method, url: req.originalUrl }, - response: { statusCode: 500 }, - }; - - res.status(500).json(body); - }, + public createRequestHandler(): RequestHandler { + return async (req, res, next) => { + const middleware = await this.getMiddleware(req); + middleware(req, res, next); }; + } - // Probably too risky without permissions protecting this endpoint - // if (clusterDetails.serviceAccountToken) { - // options.headers = { - // Authorization: `Bearer ${clusterDetails.serviceAccountToken}`, - // }; - // } - createProxyMiddleware(options)(req, res, next); - }; + // We create one middleware per remote cluster and hold on to them, because + // the secure property isn't possible to decide on a per-request basis with a + // single middleware instance - and we don't expect it to change over time. + private async getMiddleware(originalReq: Request): Promise { + const originalCluster = await this.getClusterForRequest(originalReq); + let middleware = this.middlewareForClusterName.get(originalCluster.name); + if (!middleware) { + // Probably too risky without permissions protecting this endpoint + // if (cluster.serviceAccountToken) { + // options.headers = { + // Authorization: `Bearer ${cluster.serviceAccountToken}`, + // }; + // } - private getKubernetesRequestedCluster(req: Request): string { - const requestedClusterName = req.header(HEADER_KUBERNETES_CLUSTER); + const logger = this.logger.child({ cluster: originalCluster.name }); + middleware = createProxyMiddleware({ + logProvider: () => logger, + secure: !originalCluster.skipTLSVerify, + router: async req => { + // Re-evaluate the cluster on each request, in case it has changed + const cluster = await this.getClusterForRequest(req); + const url = new URL(cluster.url); + return { + protocol: url.protocol, + host: url.hostname, + port: url.port, + ca: bufferFromFileOrString('', cluster.caData)?.toString(), + }; + }, + pathRewrite: { [`^${originalReq.baseUrl}`]: '' }, + onError: (error, req, res) => { + const wrappedError = new ForwardedError( + `Cluster '${originalCluster.name}' request error`, + error, + ); - if (!requestedClusterName) { + logger.error(wrappedError); + + const body: ErrorResponseBody = { + error: serializeError(wrappedError, { + includeStack: process.env.NODE_ENV === 'development', + }), + request: { method: req.method, url: req.originalUrl }, + response: { statusCode: 500 }, + }; + + res.status(500).json(body); + }, + }); + + this.middlewareForClusterName.set(originalCluster.name, middleware); + } + + return middleware; + } + + private async getClusterForRequest(req: Request): Promise { + const clusterName = req.header(HEADER_KUBERNETES_CLUSTER); + if (!clusterName) { throw new InputError(`Missing '${HEADER_KUBERNETES_CLUSTER}' header.`); } - return requestedClusterName; - } - - private async getClusterDetails( - requestedCluster: string, - ): Promise { - const clusters = await this.clusterSupplier.getClusters(); - - const clusterDetail = clusters.find( - cluster => cluster.name === requestedCluster, - ); - - if (!clusterDetail) { - throw new NotFoundError(`Cluster '${requestedCluster}' not found`); + const cluster = await this.clusterSupplier + .getClusters() + .then(clusters => clusters.find(c => c.name === clusterName)); + if (!cluster) { + throw new NotFoundError(`Cluster '${clusterName}' not found`); } - return clusterDetail; + return cluster; } } From db4089d33cb275afc4dc41f9b5ee2b67060859ae Mon Sep 17 00:00:00 2001 From: Thorsten Hake Date: Tue, 22 Nov 2022 13:58:27 +0100 Subject: [PATCH 55/83] updated yarn.lock and api-report.md Signed-off-by: Thorsten Hake --- plugins/catalog-backend-module-openapi/api-report.md | 10 +++++----- yarn.lock | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/catalog-backend-module-openapi/api-report.md b/plugins/catalog-backend-module-openapi/api-report.md index 7294fd5936..c2af9cbe01 100644 --- a/plugins/catalog-backend-module-openapi/api-report.md +++ b/plugins/catalog-backend-module-openapi/api-report.md @@ -13,6 +13,11 @@ import { PlaceholderResolverParams } from '@backstage/plugin-catalog-backend'; import { ScmIntegrations } from '@backstage/integration'; import { UrlReader } from '@backstage/backend-common'; +// @public (undocumented) +export function jsonSchemaRefPlaceholderResolver( + params: PlaceholderResolverParams, +): Promise; + // @public @deprecated (undocumented) export const openApiPlaceholderResolver: typeof jsonSchemaRefPlaceholderResolver; @@ -37,10 +42,5 @@ export class OpenApiRefProcessor implements CatalogProcessor { preProcessEntity(entity: Entity, location: LocationSpec): Promise; } -// @public (undocumented) -export function jsonSchemaRefPlaceholderResolver( - params: PlaceholderResolverParams, -): Promise; - // (No @packageDocumentation comment for this package) ``` diff --git a/yarn.lock b/yarn.lock index 96b7ddbf8b..959d6a3453 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15118,7 +15118,7 @@ __metadata: languageName: node linkType: hard -"ajv8@npm:ajv@^8.11.0, ajv@npm:^8.0.0, ajv@npm:^8.10.0, ajv@npm:^8.6.3, ajv@npm:^8.8.0": +"ajv8@npm:ajv@^8.11.0, ajv@npm:^8.0.0, ajv@npm:^8.10.0, ajv@npm:^8.8.0": version: 8.11.2 resolution: "ajv@npm:8.11.2" dependencies: From 92e558f4cfbe19e5bba27bbe16b549028df89ee1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Tue, 22 Nov 2022 14:10:09 +0100 Subject: [PATCH 56/83] use the right msw version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- plugins/kubernetes-backend/package.json | 2 +- yarn.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/kubernetes-backend/package.json b/plugins/kubernetes-backend/package.json index 9c6cfd0563..c0822d366a 100644 --- a/plugins/kubernetes-backend/package.json +++ b/plugins/kubernetes-backend/package.json @@ -70,7 +70,7 @@ "@types/aws4": "^1.5.1", "@types/http-proxy-middleware": "^0.19.3", "aws-sdk-mock": "^5.2.1", - "msw": "^0.48.0", + "msw": "^0.49.0", "supertest": "^6.1.3" }, "files": [ diff --git a/yarn.lock b/yarn.lock index b049053f9e..282fdcba98 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5992,7 +5992,7 @@ __metadata: lodash: ^4.17.21 luxon: ^3.0.0 morgan: ^1.10.0 - msw: ^0.48.0 + msw: ^0.49.0 node-fetch: ^2.6.7 stream-buffers: ^3.0.2 supertest: ^6.1.3 From 8a19bd7c1a0abe077bb1a115b1699db2720952ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?MALIN=20WID=C3=88N?= Date: Tue, 22 Nov 2022 14:38:15 +0100 Subject: [PATCH 57/83] add changeset to @backstage/plugin-scaffolder and @backstage/plugin-scaffolder-backend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: MALIN WIDÈN --- .changeset/cyan-pears-yawn.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/cyan-pears-yawn.md diff --git a/.changeset/cyan-pears-yawn.md b/.changeset/cyan-pears-yawn.md new file mode 100644 index 0000000000..d1329ce154 --- /dev/null +++ b/.changeset/cyan-pears-yawn.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-scaffolder': minor +'@backstage/plugin-scaffolder-backend': minor +--- + +Fixed deprecations in plugin/scaffolder and /plugin/scaffolder-backend From f45c3017ba3a84c9e5aa575e367bc0e921040c7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?MALIN=20WID=C3=88N?= Date: Tue, 22 Nov 2022 14:48:34 +0100 Subject: [PATCH 58/83] Put back createPublishBitbucketAction in index.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: MALIN WIDÈN --- .../src/scaffolder/actions/builtin/publish/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/index.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/index.ts index 37969c18c0..a8a40ab1df 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/index.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/index.ts @@ -15,6 +15,7 @@ */ export { createPublishAzureAction } from './azure'; +export { createPublishBitbucketAction } from './bitbucket'; export { createPublishBitbucketCloudAction } from './bitbucketCloud'; export { createPublishBitbucketServerAction } from './bitbucketServer'; export { createPublishGerritAction } from './gerrit'; From ddd5c87ffb49fc313d27181d8855dbd3054cb016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?MALIN=20WID=C3=88N?= Date: Tue, 22 Nov 2022 15:35:50 +0100 Subject: [PATCH 59/83] Change Buffer.from to window.btoa MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: MALIN WIDÈN --- .../components/TemplateEditorPage/DryRunContext.test.tsx | 4 ++-- .../src/components/TemplateEditorPage/DryRunContext.tsx | 6 +++--- .../DryRunResults/DryRunResultsView.test.tsx | 3 +-- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/plugins/scaffolder/src/components/TemplateEditorPage/DryRunContext.test.tsx b/plugins/scaffolder/src/components/TemplateEditorPage/DryRunContext.test.tsx index 91fb3d934f..36a62f1b8a 100644 --- a/plugins/scaffolder/src/components/TemplateEditorPage/DryRunContext.test.tsx +++ b/plugins/scaffolder/src/components/TemplateEditorPage/DryRunContext.test.tsx @@ -25,7 +25,7 @@ describe('base64EncodeContent', () => { it('encodes text files', () => { expect(base64EncodeContent('abc')).toBe('YWJj'); expect(base64EncodeContent('abc'.repeat(1000000))).toBe( - Buffer.from('').toString('base64'), + window.btoa(''), ); }); @@ -38,7 +38,7 @@ describe('base64EncodeContent', () => { ); // Triggers size check expect(base64EncodeContent('😅'.repeat(1000000))).toBe( - Buffer.from('').toString('base64'), + window.btoa(''), ); }); }); diff --git a/plugins/scaffolder/src/components/TemplateEditorPage/DryRunContext.tsx b/plugins/scaffolder/src/components/TemplateEditorPage/DryRunContext.tsx index 17e077e47c..3534b62c39 100644 --- a/plugins/scaffolder/src/components/TemplateEditorPage/DryRunContext.tsx +++ b/plugins/scaffolder/src/components/TemplateEditorPage/DryRunContext.tsx @@ -59,11 +59,11 @@ interface DryRunProviderProps { export function base64EncodeContent(content: string): string { if (content.length > MAX_CONTENT_SIZE) { - return Buffer.from('').toString('base64'); + return window.btoa(''); } try { - return Buffer.from(content).toString('base64'); + return window.btoa(content); } catch { const decoder = new TextEncoder(); const buffer = decoder.encode(content); @@ -74,7 +74,7 @@ export function base64EncodeContent(content: string): string { String.fromCharCode(...buffer.slice(offset, offset + CHUNK_SIZE)), ); } - return Buffer.from(chunks.join('')).toString('base64'); + return window.btoa(chunks.join('')); } } diff --git a/plugins/scaffolder/src/components/TemplateEditorPage/DryRunResults/DryRunResultsView.test.tsx b/plugins/scaffolder/src/components/TemplateEditorPage/DryRunResults/DryRunResultsView.test.tsx index 106ee0379f..c709adfd68 100644 --- a/plugins/scaffolder/src/components/TemplateEditorPage/DryRunResults/DryRunResultsView.test.tsx +++ b/plugins/scaffolder/src/components/TemplateEditorPage/DryRunResults/DryRunResultsView.test.tsx @@ -58,8 +58,7 @@ describe('DryRunResultsView', () => { directoryContents: [ { path: 'foo.txt', - base64Content: - Buffer.from('Foo Content').toString('base64'), + base64Content: window.btoa('Foo Content'), executable: false, }, ], From 09c91404ea03d0362bef0da5cd1b08239c5fd5a3 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 22 Nov 2022 15:36:47 +0100 Subject: [PATCH 60/83] scripts/patch-release-for-pr: fix version check point and keep diff points Signed-off-by: Patrik Oldsberg --- .github/workflows/automate_merge_message.yml | 4 ++-- scripts/generate-merge-message.js | 18 ++++++++++++------ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/.github/workflows/automate_merge_message.yml b/.github/workflows/automate_merge_message.yml index 7ad4aa8fdd..c376f7d0f3 100644 --- a/.github/workflows/automate_merge_message.yml +++ b/.github/workflows/automate_merge_message.yml @@ -25,7 +25,7 @@ jobs: steps: - uses: actions/checkout@v3 with: - ref: '${{ github.event.pull_request.head.sha }}' + ref: '${{ github.event.pull_request.merge_commit_sha }}' - name: fetch base run: git fetch --depth 1 origin ${{ github.event.pull_request.base.sha }} @@ -36,7 +36,7 @@ jobs: run: | rm -f generate.js wget -O generate.js https://raw.githubusercontent.com/backstage/backstage/master/scripts/generate-merge-message.js 1>&2 - node generate.js FETCH_HEAD > message.txt + node generate.js ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }} > message.txt - name: Post Message uses: actions/github-script@v6 diff --git a/scripts/generate-merge-message.js b/scripts/generate-merge-message.js index 9b6fb5cbc6..ab8df55d20 100755 --- a/scripts/generate-merge-message.js +++ b/scripts/generate-merge-message.js @@ -21,15 +21,20 @@ const { resolve: resolvePath } = require('path'); const execFile = promisify(execFileCb); -async function hasNewChangesets(ref) { - if (!ref) { - throw new Error('ref is required'); +async function hasNewChangesets(baseRef, headRef) { + if (!baseRef) { + throw new Error('baseRef is required'); + } + if (!headRef) { + throw new Error('headRef is required'); } const { stdout } = await execFile('git', [ 'diff', '--compact-summary', - ref, + baseRef, + headRef, + '--', '.changeset/*.md', ]); return stdout.includes('(new)'); @@ -88,8 +93,9 @@ function findNextRelease(currentRelease, releaseSchedule) { } async function main() { - const [diffRef = 'origin/master'] = process.argv.slice(2); - const needsMessage = await hasNewChangesets(diffRef); + const [diffBaseRefRef = 'origin/master', diffHeadRef = 'HEAD'] = + process.argv.slice(2); + const needsMessage = await hasNewChangesets(diffBaseRefRef, diffHeadRef); if (!needsMessage) { return; } From 3bc5ee61297120e82d4084d4c0df76096c2f890b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?MALIN=20WID=C3=88N?= Date: Tue, 22 Nov 2022 15:36:53 +0100 Subject: [PATCH 61/83] Put back createPublishBitbucketAction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: MALIN WIDÈN --- .../src/scaffolder/actions/builtin/createBuiltinActions.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts index 6f4543673f..e388a70f00 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts @@ -45,6 +45,7 @@ import { } from './github'; import { createPublishAzureAction, + createPublishBitbucketAction, createPublishBitbucketCloudAction, createPublishBitbucketServerAction, createPublishGerritAction, @@ -141,6 +142,10 @@ export const createBuiltinActions = ( createPublishGitlabMergeRequestAction({ integrations, }), + createPublishBitbucketAction({ + integrations, + config, + }), createPublishBitbucketCloudAction({ integrations, config, From d3fea4ae0ac411fed3b22143a2e13536c6968f01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Tue, 22 Nov 2022 15:36:22 +0100 Subject: [PATCH 62/83] avoid globals MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/eight-spiders-know.md | 15 ++ .eslintrc.js | 174 ++++++++++++++++++ .github/vale/Vocab/Backstage/accept.txt | 1 + packages/backend-common/src/scm/git.ts | 2 +- .../IdentityApi/AppIdentityProxy.test.ts | 2 +- .../IdentityApi/AppIdentityProxy.ts | 2 +- .../lib/AuthConnector/DefaultAuthConnector.ts | 2 +- .../HorizontalScrollGrid.tsx | 4 +- .../version-bridge/src/lib/globalObject.ts | 2 + .../AnalyticsApi/GoogleAnalytics.ts | 2 +- .../EntityContextMenu/EntityContextMenu.tsx | 2 +- .../WorkflowRunDetails/WorkflowRunDetails.tsx | 1 + .../ProjectDetailsPage/ProjectDetailsPage.tsx | 4 +- .../WorkflowRunDetails/WorkflowRunDetails.tsx | 4 +- .../WorkflowRunLogs/WorkflowRunLogs.tsx | 2 - .../graphiql/src/lib/storage/StorageBucket.ts | 2 +- .../src/TextSize/TextSize.test.tsx | 8 +- .../transformers/copyToClipboard.test.ts | 2 +- .../reader/transformers/copyToClipboard.tsx | 2 +- 19 files changed, 212 insertions(+), 21 deletions(-) create mode 100644 .changeset/eight-spiders-know.md diff --git a/.changeset/eight-spiders-know.md b/.changeset/eight-spiders-know.md new file mode 100644 index 0000000000..2e3e54dc0f --- /dev/null +++ b/.changeset/eight-spiders-know.md @@ -0,0 +1,15 @@ +--- +'@backstage/backend-common': patch +'@backstage/core-app-api': patch +'@backstage/core-components': patch +'@backstage/version-bridge': patch +'@backstage/plugin-analytics-module-ga': patch +'@backstage/plugin-catalog': patch +'@backstage/plugin-cloudbuild': patch +'@backstage/plugin-gcp-projects': patch +'@backstage/plugin-github-actions': patch +'@backstage/plugin-graphiql': patch +'@backstage/plugin-techdocs': patch +--- + +Internal fixes to avoid implicit usage of globals diff --git a/.eslintrc.js b/.eslintrc.js index 6d07fab291..0257a2af1e 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -50,5 +50,179 @@ module.exports = { 'testing-library/no-await-sync-query': 'error', 'testing-library/prefer-wait-for': 'error', 'testing-library/no-dom-import': 'error', + 'no-restricted-globals': [ + 'error', + 'postMessage', + 'blur', + 'focus', + 'close', + 'frames', + 'self', + 'parent', + 'opener', + 'top', + 'length', + 'closed', + 'location', + 'origin', + 'name', + 'locationbar', + 'menubar', + 'personalbar', + 'scrollbars', + 'statusbar', + 'toolbar', + 'status', + 'frameElement', + 'navigator', + 'customElements', + 'external', + 'screen', + 'innerWidth', + 'innerHeight', + 'scrollX', + 'pageXOffset', + 'scrollY', + 'pageYOffset', + 'screenX', + 'screenY', + 'outerWidth', + 'outerHeight', + 'devicePixelRatio', + 'clientInformation', + 'screenLeft', + 'screenTop', + 'defaultStatus', + 'defaultstatus', + 'styleMedia', + 'onanimationend', + 'onanimationiteration', + 'onanimationstart', + 'onsearch', + 'ontransitionend', + 'onwebkitanimationend', + 'onwebkitanimationiteration', + 'onwebkitanimationstart', + 'onwebkittransitionend', + 'isSecureContext', + 'onabort', + 'onblur', + 'oncancel', + 'oncanplay', + 'oncanplaythrough', + 'onchange', + 'onclick', + 'onclose', + 'oncontextmenu', + 'oncuechange', + 'ondblclick', + 'ondrag', + 'ondragend', + 'ondragenter', + 'ondragleave', + 'ondragover', + 'ondragstart', + 'ondrop', + 'ondurationchange', + 'onemptied', + 'onended', + 'onerror', + 'onfocus', + 'oninput', + 'oninvalid', + 'onkeydown', + 'onkeypress', + 'onkeyup', + 'onload', + 'onloadeddata', + 'onloadedmetadata', + 'onloadstart', + 'onmousedown', + 'onmouseenter', + 'onmouseleave', + 'onmousemove', + 'onmouseout', + 'onmouseover', + 'onmouseup', + 'onmousewheel', + 'onpause', + 'onplay', + 'onplaying', + 'onprogress', + 'onratechange', + 'onreset', + 'onresize', + 'onscroll', + 'onseeked', + 'onseeking', + 'onselect', + 'onstalled', + 'onsubmit', + 'onsuspend', + 'ontimeupdate', + 'ontoggle', + 'onvolumechange', + 'onwaiting', + 'onwheel', + 'onauxclick', + 'ongotpointercapture', + 'onlostpointercapture', + 'onpointerdown', + 'onpointermove', + 'onpointerup', + 'onpointercancel', + 'onpointerover', + 'onpointerout', + 'onpointerenter', + 'onpointerleave', + 'onafterprint', + 'onbeforeprint', + 'onbeforeunload', + 'onhashchange', + 'onlanguagechange', + 'onmessage', + 'onmessageerror', + 'onoffline', + 'ononline', + 'onpagehide', + 'onpageshow', + 'onpopstate', + 'onrejectionhandled', + 'onstorage', + 'onunhandledrejection', + 'onunload', + 'performance', + 'stop', + 'open', + 'print', + 'captureEvents', + 'releaseEvents', + 'getComputedStyle', + 'matchMedia', + 'moveTo', + 'moveBy', + 'resizeTo', + 'resizeBy', + 'getSelection', + 'find', + 'createImageBitmap', + 'scroll', + 'scrollTo', + 'scrollBy', + 'onappinstalled', + 'onbeforeinstallprompt', + 'crypto', + 'ondevicemotion', + 'ondeviceorientation', + 'ondeviceorientationabsolute', + 'indexedDB', + 'webkitStorageInfo', + 'chrome', + 'visualViewport', + 'speechSynthesis', + 'webkitRequestFileSystem', + 'webkitResolveLocalFileSystemURL', + 'openDatabase', + ], }, }; diff --git a/.github/vale/Vocab/Backstage/accept.txt b/.github/vale/Vocab/Backstage/accept.txt index f2b3ac0b09..620432376d 100644 --- a/.github/vale/Vocab/Backstage/accept.txt +++ b/.github/vale/Vocab/Backstage/accept.txt @@ -126,6 +126,7 @@ github Gitiles gitlab GitLab +globals Gource Grafana graphql diff --git a/packages/backend-common/src/scm/git.ts b/packages/backend-common/src/scm/git.ts index 0c9252cb64..ea28ffb9b2 100644 --- a/packages/backend-common/src/scm/git.ts +++ b/packages/backend-common/src/scm/git.ts @@ -179,7 +179,7 @@ export class Git { }); } catch (ex) { this.config.logger?.error( - `Failed to fetch repo {dir=${dir},origin=${origin}}`, + `Failed to fetch repo {dir=${dir},remote=${remote}}`, ); if (ex.data) { throw new Error(`${ex.message} {data=${JSON.stringify(ex.data)}}`); diff --git a/packages/core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy.test.ts b/packages/core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy.test.ts index 6fa46db7c9..5993543c33 100644 --- a/packages/core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy.test.ts +++ b/packages/core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy.test.ts @@ -89,6 +89,6 @@ describe('AppIdentityProxy', () => { }); await proxy.signOut(); - expect(location.href).toBe('/foo'); + expect(window.location.href).toBe('/foo'); }); }); diff --git a/packages/core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy.ts b/packages/core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy.ts index 2df351bc18..4a51444879 100644 --- a/packages/core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy.ts +++ b/packages/core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy.ts @@ -124,6 +124,6 @@ export class AppIdentityProxy implements IdentityApi { async signOut(): Promise { await this.waitForTarget.then(target => target.signOut()); - location.href = this.signOutTargetUrl; + window.location.href = this.signOutTargetUrl; } } diff --git a/packages/core-app-api/src/lib/AuthConnector/DefaultAuthConnector.ts b/packages/core-app-api/src/lib/AuthConnector/DefaultAuthConnector.ts index a467957063..988c9f17b1 100644 --- a/packages/core-app-api/src/lib/AuthConnector/DefaultAuthConnector.ts +++ b/packages/core-app-api/src/lib/AuthConnector/DefaultAuthConnector.ts @@ -154,7 +154,7 @@ export class DefaultAuthConnector const scope = this.joinScopesFunc(scopes); const popupUrl = await this.buildUrl('/start', { scope, - origin: location.origin, + origin: window.location.origin, }); const payload = await showLoginPopup({ diff --git a/packages/core-components/src/components/HorizontalScrollGrid/HorizontalScrollGrid.tsx b/packages/core-components/src/components/HorizontalScrollGrid/HorizontalScrollGrid.tsx index 8c5dc4d530..4ab49596fe 100644 --- a/packages/core-components/src/components/HorizontalScrollGrid/HorizontalScrollGrid.tsx +++ b/packages/core-components/src/components/HorizontalScrollGrid/HorizontalScrollGrid.tsx @@ -155,7 +155,7 @@ function useScrollDistance( return [scrollLeft, scrollRight]; } -// Used to animate scrolling. Returns a single setScrollTarger function, when called with e.g. 200, +// Used to animate scrolling. Returns a single setScrollTarget function, when called with e.g. 200, // the element pointer to by the ref will be scrolled 200px forwards over time. function useSmoothScroll( ref: React.MutableRefObject, @@ -169,7 +169,7 @@ function useSmoothScroll( return; } - const startTime = performance.now(); + const startTime = window.performance.now(); const id = requestAnimationFrame(frameTime => { if (!ref.current) { return; diff --git a/packages/version-bridge/src/lib/globalObject.ts b/packages/version-bridge/src/lib/globalObject.ts index b29e81e4a0..19b6b73ccf 100644 --- a/packages/version-bridge/src/lib/globalObject.ts +++ b/packages/version-bridge/src/lib/globalObject.ts @@ -19,7 +19,9 @@ function getGlobalObject() { if (typeof window !== 'undefined' && window.Math === Math) { return window; } + // eslint-disable-next-line no-restricted-globals if (typeof self !== 'undefined' && self.Math === Math) { + // eslint-disable-next-line no-restricted-globals return self; } // eslint-disable-next-line no-new-func diff --git a/plugins/analytics-module-ga/src/apis/implementations/AnalyticsApi/GoogleAnalytics.ts b/plugins/analytics-module-ga/src/apis/implementations/AnalyticsApi/GoogleAnalytics.ts index ad7205983c..498b118d0d 100644 --- a/plugins/analytics-module-ga/src/apis/implementations/AnalyticsApi/GoogleAnalytics.ts +++ b/plugins/analytics-module-ga/src/apis/implementations/AnalyticsApi/GoogleAnalytics.ts @@ -241,7 +241,7 @@ export class GoogleAnalytics implements AnalyticsApi { * Simple hash function; relies on web cryptography + the sha-256 algorithm. */ private async hash(value: string): Promise { - const digest = await crypto.subtle.digest( + const digest = await window.crypto.subtle.digest( 'sha-256', new TextEncoder().encode(value), ); diff --git a/plugins/catalog/src/components/EntityContextMenu/EntityContextMenu.tsx b/plugins/catalog/src/components/EntityContextMenu/EntityContextMenu.tsx index 49952bdffe..f7a329c7be 100644 --- a/plugins/catalog/src/components/EntityContextMenu/EntityContextMenu.tsx +++ b/plugins/catalog/src/components/EntityContextMenu/EntityContextMenu.tsx @@ -89,7 +89,7 @@ export function EntityContextMenu(props: EntityContextMenuProps) { const alertApi = useApi(alertApiRef); const copyToClipboard = useCallback(() => { - navigator.clipboard + window.navigator.clipboard .writeText(window.location.toString()) .then(() => alertApi.post({ message: 'Copied!', severity: 'info' })); }, [alertApi]); diff --git a/plugins/cloudbuild/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx b/plugins/cloudbuild/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx index aacb437e7b..a35d9b6f6c 100644 --- a/plugins/cloudbuild/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx +++ b/plugins/cloudbuild/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { Entity } from '@backstage/catalog-model'; import { Box, diff --git a/plugins/gcp-projects/src/components/ProjectDetailsPage/ProjectDetailsPage.tsx b/plugins/gcp-projects/src/components/ProjectDetailsPage/ProjectDetailsPage.tsx index b900b81695..364033ce73 100644 --- a/plugins/gcp-projects/src/components/ProjectDetailsPage/ProjectDetailsPage.tsx +++ b/plugins/gcp-projects/src/components/ProjectDetailsPage/ProjectDetailsPage.tsx @@ -61,7 +61,9 @@ const DetailsPage = () => { const classes = useStyles(); const [{ status, result: details, error }, { execute }] = useAsync(async () => - api.getProject(decodeURIComponent(location.search.split('projectId=')[1])), + api.getProject( + decodeURIComponent(window.location.search.split('projectId=')[1]), + ), ); useMountEffect(execute); diff --git a/plugins/github-actions/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx b/plugins/github-actions/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx index f05ea692f5..a2c87772d5 100644 --- a/plugins/github-actions/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx +++ b/plugins/github-actions/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { Entity } from '@backstage/catalog-model'; import { readGithubIntegrationConfigs } from '@backstage/integration'; import { @@ -43,7 +44,6 @@ import { WorkflowRunStatus } from '../WorkflowRunStatus'; import { useWorkflowRunJobs } from './useWorkflowRunJobs'; import { useWorkflowRunsDetails } from './useWorkflowRunsDetails'; import { WorkflowRunLogs } from '../WorkflowRunLogs'; - import { configApiRef, useApi } from '@backstage/core-plugin-api'; import { Breadcrumbs, Link } from '@backstage/core-components'; @@ -116,8 +116,6 @@ const JobListItem = ({ } - aria-controls={`panel-${name}-content`} - id={`panel-${name}-header`} IconButtonProps={{ className: classes.button, }} diff --git a/plugins/github-actions/src/components/WorkflowRunLogs/WorkflowRunLogs.tsx b/plugins/github-actions/src/components/WorkflowRunLogs/WorkflowRunLogs.tsx index 075b73dd98..2c9d41398a 100644 --- a/plugins/github-actions/src/components/WorkflowRunLogs/WorkflowRunLogs.tsx +++ b/plugins/github-actions/src/components/WorkflowRunLogs/WorkflowRunLogs.tsx @@ -105,8 +105,6 @@ export const WorkflowRunLogs = ({ } - aria-controls={`panel-${name}-content`} - id={`panel-${name}-header`} IconButtonProps={{ className: classes.button, }} diff --git a/plugins/graphiql/src/lib/storage/StorageBucket.ts b/plugins/graphiql/src/lib/storage/StorageBucket.ts index a2b87238a6..dc2c0d4f85 100644 --- a/plugins/graphiql/src/lib/storage/StorageBucket.ts +++ b/plugins/graphiql/src/lib/storage/StorageBucket.ts @@ -47,7 +47,7 @@ export class StorageBucket implements Storage { private readonly bucket: string, ) {} - [name: string]: any; + [itemName: string]: any; get length(): number { throw new Error('Method not implemented.'); diff --git a/plugins/techdocs-module-addons-contrib/src/TextSize/TextSize.test.tsx b/plugins/techdocs-module-addons-contrib/src/TextSize/TextSize.test.tsx index 6b4a055c2a..081c718c2f 100644 --- a/plugins/techdocs-module-addons-contrib/src/TextSize/TextSize.test.tsx +++ b/plugins/techdocs-module-addons-contrib/src/TextSize/TextSize.test.tsx @@ -59,7 +59,7 @@ describe('TextSize', () => { expect(slider).toHaveTextContent('115%'); - let style = getComputedStyle(getByText('TEST_CONTENT')); + let style = window.getComputedStyle(getByText('TEST_CONTENT')); expect(style.getPropertyValue('--md-typeset-font-size')).toBe('18.4px'); @@ -73,7 +73,7 @@ describe('TextSize', () => { expect(slider).toHaveTextContent('100%'); - style = getComputedStyle(getByText('TEST_CONTENT')); + style = window.getComputedStyle(getByText('TEST_CONTENT')); expect(style.getPropertyValue('--md-typeset-font-size')).toBe('16px'); }); @@ -105,7 +105,7 @@ describe('TextSize', () => { expect(slider).toHaveTextContent('115%'); - let style = getComputedStyle(getByText('TEST_CONTENT')); + let style = window.getComputedStyle(getByText('TEST_CONTENT')); expect(style.getPropertyValue('--md-typeset-font-size')).toBe('18.4px'); @@ -117,7 +117,7 @@ describe('TextSize', () => { expect(slider).toHaveTextContent('100%'); - style = getComputedStyle(getByText('TEST_CONTENT')); + style = window.getComputedStyle(getByText('TEST_CONTENT')); expect(style.getPropertyValue('--md-typeset-font-size')).toBe('16px'); }); diff --git a/plugins/techdocs/src/reader/transformers/copyToClipboard.test.ts b/plugins/techdocs/src/reader/transformers/copyToClipboard.test.ts index 4613df374d..9c4ee08346 100644 --- a/plugins/techdocs/src/reader/transformers/copyToClipboard.test.ts +++ b/plugins/techdocs/src/reader/transformers/copyToClipboard.test.ts @@ -20,7 +20,7 @@ import { lightTheme } from '@backstage/theme'; import { waitFor } from '@testing-library/react'; const clipboardSpy = jest.fn(); -Object.defineProperty(navigator, 'clipboard', { +Object.defineProperty(window.navigator, 'clipboard', { value: { writeText: clipboardSpy, }, diff --git a/plugins/techdocs/src/reader/transformers/copyToClipboard.tsx b/plugins/techdocs/src/reader/transformers/copyToClipboard.tsx index 25a1d67f65..6adb4252d3 100644 --- a/plugins/techdocs/src/reader/transformers/copyToClipboard.tsx +++ b/plugins/techdocs/src/reader/transformers/copyToClipboard.tsx @@ -49,7 +49,7 @@ const CopyToClipboardButton = ({ text }: CopyToClipboardButtonProps) => { const [open, setOpen] = useState(false); const handleClick = useCallback(() => { - navigator.clipboard.writeText(text); + window.navigator.clipboard.writeText(text); setOpen(true); }, [text]); From 316280fe7c559cd76b9649ea65eedb8b4ff4e749 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 22 Nov 2022 16:01:03 +0100 Subject: [PATCH 63/83] enter prerelease Signed-off-by: Patrik Oldsberg --- .changeset/pre.json | 193 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 .changeset/pre.json diff --git a/.changeset/pre.json b/.changeset/pre.json new file mode 100644 index 0000000000..75ac96bbd7 --- /dev/null +++ b/.changeset/pre.json @@ -0,0 +1,193 @@ +{ + "mode": "pre", + "tag": "next", + "initialVersions": { + "example-app": "0.2.77", + "@backstage/app-defaults": "1.0.8", + "example-backend": "0.2.77", + "@backstage/backend-app-api": "0.2.3", + "@backstage/backend-common": "0.16.0", + "@backstage/backend-defaults": "0.1.3", + "example-backend-next": "0.0.5", + "@backstage/backend-plugin-api": "0.1.4", + "@backstage/backend-tasks": "0.3.7", + "@backstage/backend-test-utils": "0.1.30", + "@backstage/catalog-client": "1.1.2", + "@backstage/catalog-model": "1.1.3", + "@backstage/cli": "0.21.0", + "@backstage/cli-common": "0.1.10", + "@backstage/codemods": "0.1.41", + "@backstage/config": "1.0.4", + "@backstage/config-loader": "1.1.6", + "@backstage/core-app-api": "1.2.0", + "@backstage/core-components": "0.12.0", + "@backstage/core-plugin-api": "1.1.0", + "@backstage/create-app": "0.4.34", + "@backstage/dev-utils": "1.0.8", + "e2e-test": "0.2.0", + "@backstage/errors": "1.1.3", + "@backstage/integration": "1.4.0", + "@backstage/integration-react": "1.1.6", + "@backstage/release-manifests": "0.0.7", + "@backstage/repo-tools": "0.0.0", + "@techdocs/cli": "1.2.3", + "techdocs-cli-embedded-app": "0.2.76", + "@backstage/test-utils": "1.2.2", + "@backstage/theme": "0.2.16", + "@backstage/types": "1.0.1", + "@backstage/version-bridge": "1.0.2", + "@backstage/plugin-adr": "0.2.3", + "@backstage/plugin-adr-backend": "0.2.3", + "@backstage/plugin-adr-common": "0.2.3", + "@backstage/plugin-airbrake": "0.3.11", + "@backstage/plugin-airbrake-backend": "0.2.11", + "@backstage/plugin-allure": "0.1.27", + "@backstage/plugin-analytics-module-ga": "0.1.22", + "@backstage/plugin-apache-airflow": "0.2.4", + "@backstage/plugin-api-docs": "0.8.11", + "@backstage/plugin-api-docs-module-protoc-gen-doc": "0.1.0", + "@backstage/plugin-apollo-explorer": "0.1.4", + "@backstage/plugin-app-backend": "0.3.38", + "@backstage/plugin-auth-backend": "0.17.1", + "@backstage/plugin-auth-node": "0.2.7", + "@backstage/plugin-azure-devops": "0.2.2", + "@backstage/plugin-azure-devops-backend": "0.3.17", + "@backstage/plugin-azure-devops-common": "0.3.0", + "@backstage/plugin-azure-sites": "0.1.0", + "@backstage/plugin-azure-sites-backend": "0.1.0", + "@backstage/plugin-azure-sites-common": "0.1.0", + "@backstage/plugin-badges": "0.2.35", + "@backstage/plugin-badges-backend": "0.1.32", + "@backstage/plugin-bazaar": "0.2.0", + "@backstage/plugin-bazaar-backend": "0.2.1", + "@backstage/plugin-bitbucket-cloud-common": "0.2.1", + "@backstage/plugin-bitrise": "0.1.38", + "@backstage/plugin-catalog": "1.6.1", + "@backstage/plugin-catalog-backend": "1.5.1", + "@backstage/plugin-catalog-backend-module-aws": "0.1.11", + "@backstage/plugin-catalog-backend-module-azure": "0.1.9", + "@backstage/plugin-catalog-backend-module-bitbucket": "0.2.5", + "@backstage/plugin-catalog-backend-module-bitbucket-cloud": "0.1.5", + "@backstage/plugin-catalog-backend-module-bitbucket-server": "0.1.3", + "@backstage/plugin-catalog-backend-module-gerrit": "0.1.6", + "@backstage/plugin-catalog-backend-module-github": "0.2.0", + "@backstage/plugin-catalog-backend-module-gitlab": "0.1.9", + "@backstage/plugin-catalog-backend-module-ldap": "0.5.5", + "@backstage/plugin-catalog-backend-module-msgraph": "0.4.4", + "@backstage/plugin-catalog-backend-module-openapi": "0.1.4", + "@backstage/plugin-catalog-common": "1.0.8", + "@internal/plugin-catalog-customized": "0.0.4", + "@backstage/plugin-catalog-graph": "0.2.23", + "@backstage/plugin-catalog-graphql": "0.3.15", + "@backstage/plugin-catalog-import": "0.9.1", + "@backstage/plugin-catalog-node": "1.2.1", + "@backstage/plugin-catalog-react": "1.2.1", + "@backstage/plugin-cicd-statistics": "0.1.13", + "@backstage/plugin-cicd-statistics-module-gitlab": "0.1.7", + "@backstage/plugin-circleci": "0.3.11", + "@backstage/plugin-cloudbuild": "0.3.11", + "@backstage/plugin-code-climate": "0.1.11", + "@backstage/plugin-code-coverage": "0.2.4", + "@backstage/plugin-code-coverage-backend": "0.2.4", + "@backstage/plugin-codescene": "0.1.6", + "@backstage/plugin-config-schema": "0.1.34", + "@backstage/plugin-cost-insights": "0.12.0", + "@backstage/plugin-cost-insights-common": "0.1.1", + "@backstage/plugin-dynatrace": "1.0.1", + "@backstage/plugin-events-backend": "0.1.0", + "@backstage/plugin-events-backend-module-aws-sqs": "0.1.0", + "@backstage/plugin-events-backend-module-azure": "0.1.0", + "@backstage/plugin-events-backend-module-bitbucket-cloud": "0.1.0", + "@backstage/plugin-events-backend-module-gerrit": "0.1.0", + "@backstage/plugin-events-backend-module-github": "0.1.0", + "@backstage/plugin-events-backend-module-gitlab": "0.1.0", + "@backstage/plugin-events-backend-test-utils": "0.1.0", + "@backstage/plugin-events-node": "0.1.0", + "@internal/plugin-todo-list": "1.0.7", + "@internal/plugin-todo-list-backend": "1.0.7", + "@internal/plugin-todo-list-common": "1.0.6", + "@backstage/plugin-explore": "0.3.42", + "@backstage/plugin-explore-react": "0.0.23", + "@backstage/plugin-firehydrant": "0.1.28", + "@backstage/plugin-fossa": "0.2.43", + "@backstage/plugin-gcalendar": "0.3.7", + "@backstage/plugin-gcp-projects": "0.3.30", + "@backstage/plugin-git-release-manager": "0.3.24", + "@backstage/plugin-github-actions": "0.5.11", + "@backstage/plugin-github-deployments": "0.1.42", + "@backstage/plugin-github-issues": "0.2.0", + "@backstage/plugin-github-pull-requests-board": "0.1.5", + "@backstage/plugin-gitops-profiles": "0.3.29", + "@backstage/plugin-gocd": "0.1.17", + "@backstage/plugin-graphiql": "0.2.43", + "@backstage/plugin-graphql-backend": "0.1.28", + "@backstage/plugin-home": "0.4.27", + "@backstage/plugin-ilert": "0.2.0", + "@backstage/plugin-jenkins": "0.7.10", + "@backstage/plugin-jenkins-backend": "0.1.28", + "@backstage/plugin-jenkins-common": "0.1.10", + "@backstage/plugin-kafka": "0.3.11", + "@backstage/plugin-kafka-backend": "0.2.31", + "@backstage/plugin-kubernetes": "0.7.4", + "@backstage/plugin-kubernetes-backend": "0.8.0", + "@backstage/plugin-kubernetes-common": "0.4.4", + "@backstage/plugin-lighthouse": "0.3.11", + "@backstage/plugin-newrelic": "0.3.29", + "@backstage/plugin-newrelic-dashboard": "0.2.4", + "@backstage/plugin-org": "0.6.0", + "@backstage/plugin-org-react": "0.1.0", + "@backstage/plugin-pagerduty": "0.5.4", + "@backstage/plugin-periskop": "0.1.9", + "@backstage/plugin-periskop-backend": "0.1.9", + "@backstage/plugin-permission-backend": "0.5.13", + "@backstage/plugin-permission-common": "0.7.1", + "@backstage/plugin-permission-node": "0.7.1", + "@backstage/plugin-permission-react": "0.4.7", + "@backstage/plugin-playlist": "0.1.2", + "@backstage/plugin-playlist-backend": "0.2.1", + "@backstage/plugin-playlist-common": "0.1.2", + "@backstage/plugin-proxy-backend": "0.2.32", + "@backstage/plugin-rollbar": "0.4.11", + "@backstage/plugin-rollbar-backend": "0.1.35", + "@backstage/plugin-scaffolder": "1.8.0", + "@backstage/plugin-scaffolder-backend": "1.8.0", + "@backstage/plugin-scaffolder-backend-module-cookiecutter": "0.2.13", + "@backstage/plugin-scaffolder-backend-module-rails": "0.4.6", + "@backstage/plugin-scaffolder-backend-module-yeoman": "0.2.11", + "@backstage/plugin-scaffolder-common": "1.2.2", + "@backstage/plugin-search": "1.0.4", + "@backstage/plugin-search-backend": "1.1.1", + "@backstage/plugin-search-backend-module-elasticsearch": "1.0.4", + "@backstage/plugin-search-backend-module-pg": "0.4.2", + "@backstage/plugin-search-backend-node": "1.0.4", + "@backstage/plugin-search-common": "1.1.1", + "@backstage/plugin-search-react": "1.2.1", + "@backstage/plugin-sentry": "0.4.4", + "@backstage/plugin-shortcuts": "0.3.3", + "@backstage/plugin-sonarqube": "0.5.0", + "@backstage/plugin-sonarqube-backend": "0.1.3", + "@backstage/plugin-splunk-on-call": "0.4.0", + "@backstage/plugin-stack-overflow": "0.1.7", + "@backstage/plugin-stack-overflow-backend": "0.1.7", + "@backstage/plugin-tech-insights": "0.3.3", + "@backstage/plugin-tech-insights-backend": "0.5.4", + "@backstage/plugin-tech-insights-backend-module-jsonfc": "0.1.22", + "@backstage/plugin-tech-insights-common": "0.2.8", + "@backstage/plugin-tech-insights-node": "0.3.6", + "@backstage/plugin-tech-radar": "0.5.18", + "@backstage/plugin-techdocs": "1.4.0", + "@backstage/plugin-techdocs-addons-test-utils": "1.0.6", + "@backstage/plugin-techdocs-backend": "1.4.1", + "@backstage/plugin-techdocs-module-addons-contrib": "1.0.6", + "@backstage/plugin-techdocs-node": "1.4.2", + "@backstage/plugin-techdocs-react": "1.0.6", + "@backstage/plugin-todo": "0.2.13", + "@backstage/plugin-todo-backend": "0.1.35", + "@backstage/plugin-user-settings": "0.5.1", + "@backstage/plugin-user-settings-backend": "0.1.2", + "@backstage/plugin-vault": "0.1.5", + "@backstage/plugin-vault-backend": "0.2.4", + "@backstage/plugin-xcmetrics": "0.2.31" + }, + "changesets": [] +} From 59cb5ef9f4b91923b7c56ce97d6adca52272d00b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?MALIN=20WID=C3=88N?= Date: Tue, 22 Nov 2022 16:07:59 +0100 Subject: [PATCH 64/83] remove changeset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: MALIN WIDÈN --- .changeset/cyan-pears-yawn.md | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 .changeset/cyan-pears-yawn.md diff --git a/.changeset/cyan-pears-yawn.md b/.changeset/cyan-pears-yawn.md deleted file mode 100644 index d1329ce154..0000000000 --- a/.changeset/cyan-pears-yawn.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-scaffolder': minor -'@backstage/plugin-scaffolder-backend': minor ---- - -Fixed deprecations in plugin/scaffolder and /plugin/scaffolder-backend From e1c481e0b398cba9cc9d7282912ca5e61fafe984 Mon Sep 17 00:00:00 2001 From: Thorsten Hake Date: Tue, 22 Nov 2022 16:22:10 +0100 Subject: [PATCH 65/83] fixed test Signed-off-by: Thorsten Hake --- .../src/jsonSchemaRefPlaceholderResolver.test.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/plugins/catalog-backend-module-openapi/src/jsonSchemaRefPlaceholderResolver.test.ts b/plugins/catalog-backend-module-openapi/src/jsonSchemaRefPlaceholderResolver.test.ts index 6aecc9b468..afa523ccf0 100644 --- a/plugins/catalog-backend-module-openapi/src/jsonSchemaRefPlaceholderResolver.test.ts +++ b/plugins/catalog-backend-module-openapi/src/jsonSchemaRefPlaceholderResolver.test.ts @@ -50,9 +50,7 @@ describe('jsonSchemaRefPlaceholderResolver', () => { it('should throw error if unable to bundle the OpenAPI specification', async () => { (bundleFileWithRefs as any).mockRejectedValue(new Error('TEST')); - await expect(jsonSchemaRefPlaceholderResolver(params)).rejects.toThrow( - 'Placeholder $openapi unable to bundle OpenAPI specification', - ); + await expect(jsonSchemaRefPlaceholderResolver(params)).rejects.toThrow(); }); it('should bundle the OpenAPI specification', async () => { From 83d316759466522d13ba6d22e8b36491f25b7e49 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 22 Nov 2022 15:40:52 +0000 Subject: [PATCH 66/83] Version Packages (next) --- .changeset/create-app-1669131574.md | 5 + .changeset/pre.json | 43 +- docs/releases/v1.9.0-next.0-changelog.md | 2305 +++++++++++++++++ package.json | 2 +- packages/app-defaults/CHANGELOG.md | 11 + packages/app-defaults/package.json | 2 +- packages/app/CHANGELOG.md | 63 + packages/app/package.json | 2 +- packages/backend-app-api/CHANGELOG.md | 12 + packages/backend-app-api/package.json | 2 +- packages/backend-common/CHANGELOG.md | 14 + packages/backend-common/package.json | 2 +- packages/backend-defaults/CHANGELOG.md | 9 + packages/backend-defaults/package.json | 2 +- packages/backend-next/CHANGELOG.md | 10 + packages/backend-next/package.json | 2 +- packages/backend-plugin-api/CHANGELOG.md | 11 + packages/backend-plugin-api/package.json | 2 +- packages/backend-tasks/CHANGELOG.md | 10 + packages/backend-tasks/package.json | 2 +- packages/backend-test-utils/CHANGELOG.md | 12 + packages/backend-test-utils/package.json | 2 +- packages/backend/CHANGELOG.md | 46 + packages/backend/package.json | 2 +- packages/catalog-client/CHANGELOG.md | 13 + packages/catalog-client/package.json | 2 +- packages/catalog-model/CHANGELOG.md | 9 + packages/catalog-model/package.json | 2 +- packages/cli/CHANGELOG.md | 15 + packages/cli/package.json | 2 +- packages/config-loader/CHANGELOG.md | 11 + packages/config-loader/package.json | 2 +- packages/config/CHANGELOG.md | 7 + packages/config/package.json | 2 +- packages/core-app-api/CHANGELOG.md | 12 + packages/core-app-api/package.json | 2 +- packages/core-components/CHANGELOG.md | 17 + packages/core-components/package.json | 2 +- packages/core-plugin-api/CHANGELOG.md | 11 + packages/core-plugin-api/package.json | 2 +- packages/create-app/CHANGELOG.md | 8 + packages/create-app/package.json | 2 +- packages/dev-utils/CHANGELOG.md | 16 + packages/dev-utils/package.json | 2 +- packages/errors/CHANGELOG.md | 7 + packages/errors/package.json | 2 +- packages/integration-react/CHANGELOG.md | 12 + packages/integration-react/package.json | 2 +- packages/integration/CHANGELOG.md | 10 + packages/integration/package.json | 2 +- packages/release-manifests/CHANGELOG.md | 6 + packages/release-manifests/package.json | 2 +- packages/repo-tools/CHANGELOG.md | 12 + packages/repo-tools/package.json | 2 +- .../techdocs-cli-embedded-app/CHANGELOG.md | 19 + .../techdocs-cli-embedded-app/package.json | 2 +- packages/techdocs-cli/CHANGELOG.md | 11 + packages/techdocs-cli/package.json | 2 +- packages/test-utils/CHANGELOG.md | 15 + packages/test-utils/package.json | 2 +- packages/types/CHANGELOG.md | 6 + packages/types/package.json | 2 +- plugins/adr-backend/CHANGELOG.md | 15 + plugins/adr-backend/package.json | 2 +- plugins/adr-common/CHANGELOG.md | 9 + plugins/adr-common/package.json | 2 +- plugins/adr/CHANGELOG.md | 16 + plugins/adr/package.json | 2 +- plugins/airbrake-backend/CHANGELOG.md | 9 + plugins/airbrake-backend/package.json | 2 +- plugins/airbrake/CHANGELOG.md | 14 + plugins/airbrake/package.json | 2 +- plugins/allure/CHANGELOG.md | 12 + plugins/allure/package.json | 2 +- plugins/analytics-module-ga/CHANGELOG.md | 11 + plugins/analytics-module-ga/package.json | 2 +- plugins/apache-airflow/CHANGELOG.md | 9 + plugins/apache-airflow/package.json | 2 +- plugins/api-docs/CHANGELOG.md | 13 + plugins/api-docs/package.json | 2 +- plugins/apollo-explorer/CHANGELOG.md | 10 + plugins/apollo-explorer/package.json | 2 +- plugins/app-backend/CHANGELOG.md | 12 + plugins/app-backend/package.json | 2 +- plugins/auth-backend/CHANGELOG.md | 14 + plugins/auth-backend/package.json | 2 +- plugins/auth-node/CHANGELOG.md | 10 + plugins/auth-node/package.json | 2 +- plugins/azure-devops-backend/CHANGELOG.md | 10 + plugins/azure-devops-backend/package.json | 2 +- plugins/azure-devops/CHANGELOG.md | 14 + plugins/azure-devops/package.json | 2 +- plugins/azure-sites-backend/CHANGELOG.md | 10 + plugins/azure-sites-backend/package.json | 2 +- plugins/azure-sites/CHANGELOG.md | 13 + plugins/azure-sites/package.json | 2 +- plugins/badges-backend/CHANGELOG.md | 11 + plugins/badges-backend/package.json | 2 +- plugins/badges/CHANGELOG.md | 13 + plugins/badges/package.json | 2 +- plugins/bazaar-backend/CHANGELOG.md | 11 + plugins/bazaar-backend/package.json | 2 +- plugins/bazaar/CHANGELOG.md | 14 + plugins/bazaar/package.json | 2 +- plugins/bitbucket-cloud-common/CHANGELOG.md | 8 + plugins/bitbucket-cloud-common/package.json | 2 +- plugins/bitrise/CHANGELOG.md | 12 + plugins/bitrise/package.json | 2 +- .../catalog-backend-module-aws/CHANGELOG.md | 16 + .../catalog-backend-module-aws/package.json | 2 +- .../catalog-backend-module-azure/CHANGELOG.md | 17 + .../catalog-backend-module-azure/package.json | 2 +- .../CHANGELOG.md | 19 + .../package.json | 2 +- .../CHANGELOG.md | 16 + .../package.json | 2 +- .../CHANGELOG.md | 15 + .../package.json | 2 +- .../CHANGELOG.md | 16 + .../package.json | 2 +- .../CHANGELOG.md | 20 + .../package.json | 2 +- .../CHANGELOG.md | 17 + .../package.json | 2 +- .../catalog-backend-module-ldap/CHANGELOG.md | 12 + .../catalog-backend-module-ldap/package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- plugins/catalog-backend/CHANGELOG.md | 30 + plugins/catalog-backend/package.json | 2 +- plugins/catalog-common/CHANGELOG.md | 9 + plugins/catalog-common/package.json | 2 +- plugins/catalog-customized/CHANGELOG.md | 8 + plugins/catalog-customized/package.json | 2 +- plugins/catalog-graph/CHANGELOG.md | 13 + plugins/catalog-graph/package.json | 2 +- plugins/catalog-graphql/CHANGELOG.md | 10 + plugins/catalog-graphql/package.json | 2 +- plugins/catalog-import/CHANGELOG.md | 17 + plugins/catalog-import/package.json | 2 +- plugins/catalog-node/CHANGELOG.md | 12 + plugins/catalog-node/package.json | 2 +- plugins/catalog-react/CHANGELOG.md | 19 + plugins/catalog-react/package.json | 2 +- plugins/catalog/CHANGELOG.md | 20 + plugins/catalog/package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- plugins/cicd-statistics/CHANGELOG.md | 9 + plugins/cicd-statistics/package.json | 2 +- plugins/circleci/CHANGELOG.md | 12 + plugins/circleci/package.json | 2 +- plugins/cloudbuild/CHANGELOG.md | 12 + plugins/cloudbuild/package.json | 2 +- plugins/code-climate/CHANGELOG.md | 12 + plugins/code-climate/package.json | 2 +- plugins/code-coverage-backend/CHANGELOG.md | 13 + plugins/code-coverage-backend/package.json | 2 +- plugins/code-coverage/CHANGELOG.md | 14 + plugins/code-coverage/package.json | 2 +- plugins/codescene/CHANGELOG.md | 13 + plugins/codescene/package.json | 2 +- plugins/config-schema/CHANGELOG.md | 14 + plugins/config-schema/package.json | 2 +- plugins/cost-insights/CHANGELOG.md | 15 + plugins/cost-insights/package.json | 2 +- plugins/dynatrace/CHANGELOG.md | 12 + plugins/dynatrace/package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../events-backend-module-azure/CHANGELOG.md | 8 + .../events-backend-module-azure/package.json | 2 +- .../CHANGELOG.md | 8 + .../package.json | 2 +- .../events-backend-module-gerrit/CHANGELOG.md | 8 + .../events-backend-module-gerrit/package.json | 2 +- .../events-backend-module-github/CHANGELOG.md | 8 + .../events-backend-module-github/package.json | 2 +- .../events-backend-module-gitlab/CHANGELOG.md | 8 + .../events-backend-module-gitlab/package.json | 2 +- .../events-backend-test-utils/CHANGELOG.md | 7 + .../events-backend-test-utils/package.json | 2 +- plugins/events-backend/CHANGELOG.md | 35 + plugins/events-backend/package.json | 2 +- plugins/events-node/CHANGELOG.md | 14 + plugins/events-node/package.json | 2 +- .../example-todo-list-backend/CHANGELOG.md | 10 + .../example-todo-list-backend/package.json | 2 +- plugins/example-todo-list-common/CHANGELOG.md | 7 + plugins/example-todo-list-common/package.json | 2 +- plugins/example-todo-list/CHANGELOG.md | 9 + plugins/example-todo-list/package.json | 2 +- plugins/explore-react/CHANGELOG.md | 8 + plugins/explore-react/package.json | 2 +- plugins/explore/CHANGELOG.md | 14 + plugins/explore/package.json | 2 +- plugins/firehydrant/CHANGELOG.md | 11 + plugins/firehydrant/package.json | 2 +- plugins/fossa/CHANGELOG.md | 13 + plugins/fossa/package.json | 2 +- plugins/gcalendar/CHANGELOG.md | 11 + plugins/gcalendar/package.json | 2 +- plugins/gcp-projects/CHANGELOG.md | 10 + plugins/gcp-projects/package.json | 2 +- plugins/git-release-manager/CHANGELOG.md | 11 + plugins/git-release-manager/package.json | 2 +- plugins/github-actions/CHANGELOG.md | 13 + plugins/github-actions/package.json | 2 +- plugins/github-deployments/CHANGELOG.md | 15 + plugins/github-deployments/package.json | 2 +- plugins/github-issues/CHANGELOG.md | 14 + plugins/github-issues/package.json | 2 +- .../github-pull-requests-board/CHANGELOG.md | 13 + .../github-pull-requests-board/package.json | 2 +- plugins/gitops-profiles/CHANGELOG.md | 10 + plugins/gitops-profiles/package.json | 2 +- plugins/gocd/CHANGELOG.md | 13 + plugins/gocd/package.json | 2 +- plugins/graphiql/CHANGELOG.md | 10 + plugins/graphiql/package.json | 2 +- plugins/graphql-backend/CHANGELOG.md | 10 + plugins/graphql-backend/package.json | 2 +- plugins/home/CHANGELOG.md | 14 + plugins/home/package.json | 2 +- plugins/ilert/CHANGELOG.md | 13 + plugins/ilert/package.json | 2 +- plugins/jenkins-backend/CHANGELOG.md | 15 + plugins/jenkins-backend/package.json | 2 +- plugins/jenkins-common/CHANGELOG.md | 8 + plugins/jenkins-common/package.json | 2 +- plugins/jenkins/CHANGELOG.md | 14 + plugins/jenkins/package.json | 2 +- plugins/kafka-backend/CHANGELOG.md | 10 + plugins/kafka-backend/package.json | 2 +- plugins/kafka/CHANGELOG.md | 13 + plugins/kafka/package.json | 2 +- plugins/kubernetes-backend/CHANGELOG.md | 15 + plugins/kubernetes-backend/package.json | 2 +- plugins/kubernetes-common/CHANGELOG.md | 8 + plugins/kubernetes-common/package.json | 2 +- plugins/kubernetes/CHANGELOG.md | 14 + plugins/kubernetes/package.json | 2 +- plugins/lighthouse/CHANGELOG.md | 13 + plugins/lighthouse/package.json | 2 +- plugins/newrelic-dashboard/CHANGELOG.md | 11 + plugins/newrelic-dashboard/package.json | 2 +- plugins/newrelic/CHANGELOG.md | 10 + plugins/newrelic/package.json | 2 +- plugins/org-react/CHANGELOG.md | 14 + plugins/org-react/package.json | 2 +- plugins/org/CHANGELOG.md | 12 + plugins/org/package.json | 2 +- plugins/pagerduty/CHANGELOG.md | 14 + plugins/pagerduty/package.json | 2 +- plugins/periskop-backend/CHANGELOG.md | 9 + plugins/periskop-backend/package.json | 2 +- plugins/periskop/CHANGELOG.md | 13 + plugins/periskop/package.json | 2 +- plugins/permission-backend/CHANGELOG.md | 13 + plugins/permission-backend/package.json | 2 +- plugins/permission-common/CHANGELOG.md | 10 + plugins/permission-common/package.json | 2 +- plugins/permission-node/CHANGELOG.md | 12 + plugins/permission-node/package.json | 2 +- plugins/permission-react/CHANGELOG.md | 9 + plugins/permission-react/package.json | 2 +- plugins/playlist-backend/CHANGELOG.md | 17 + plugins/playlist-backend/package.json | 2 +- plugins/playlist-common/CHANGELOG.md | 7 + plugins/playlist-common/package.json | 2 +- plugins/playlist/CHANGELOG.md | 18 + plugins/playlist/package.json | 2 +- plugins/proxy-backend/CHANGELOG.md | 9 + plugins/proxy-backend/package.json | 2 +- plugins/rollbar-backend/CHANGELOG.md | 9 + plugins/rollbar-backend/package.json | 2 +- plugins/rollbar/CHANGELOG.md | 12 + plugins/rollbar/package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- plugins/scaffolder-backend/CHANGELOG.md | 23 + plugins/scaffolder-backend/package.json | 2 +- plugins/scaffolder-common/CHANGELOG.md | 8 + plugins/scaffolder-common/package.json | 2 +- plugins/scaffolder/CHANGELOG.md | 37 + plugins/scaffolder/package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- plugins/search-backend-module-pg/CHANGELOG.md | 10 + plugins/search-backend-module-pg/package.json | 2 +- plugins/search-backend-node/CHANGELOG.md | 15 + plugins/search-backend-node/package.json | 2 +- plugins/search-backend/CHANGELOG.md | 15 + plugins/search-backend/package.json | 2 +- plugins/search-common/CHANGELOG.md | 8 + plugins/search-common/package.json | 2 +- plugins/search-react/CHANGELOG.md | 12 + plugins/search-react/package.json | 2 +- plugins/search/CHANGELOG.md | 18 + plugins/search/package.json | 2 +- plugins/sentry/CHANGELOG.md | 12 + plugins/sentry/package.json | 2 +- plugins/shortcuts/CHANGELOG.md | 12 + plugins/shortcuts/package.json | 2 +- plugins/sonarqube-backend/CHANGELOG.md | 10 + plugins/sonarqube-backend/package.json | 2 +- plugins/sonarqube/CHANGELOG.md | 13 + plugins/sonarqube/package.json | 2 +- plugins/splunk-on-call/CHANGELOG.md | 13 + plugins/splunk-on-call/package.json | 2 +- plugins/stack-overflow-backend/CHANGELOG.md | 9 + plugins/stack-overflow-backend/package.json | 2 +- plugins/stack-overflow/CHANGELOG.md | 13 + plugins/stack-overflow/package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- plugins/tech-insights-backend/CHANGELOG.md | 15 + plugins/tech-insights-backend/package.json | 2 +- plugins/tech-insights-common/CHANGELOG.md | 7 + plugins/tech-insights-common/package.json | 2 +- plugins/tech-insights-node/CHANGELOG.md | 11 + plugins/tech-insights-node/package.json | 2 +- plugins/tech-insights/CHANGELOG.md | 15 + plugins/tech-insights/package.json | 2 +- plugins/tech-radar/CHANGELOG.md | 10 + plugins/tech-radar/package.json | 2 +- .../techdocs-addons-test-utils/CHANGELOG.md | 17 + .../techdocs-addons-test-utils/package.json | 2 +- plugins/techdocs-backend/CHANGELOG.md | 17 + plugins/techdocs-backend/package.json | 2 +- .../CHANGELOG.md | 14 + .../package.json | 2 +- plugins/techdocs-node/CHANGELOG.md | 12 + plugins/techdocs-node/package.json | 2 +- plugins/techdocs-react/CHANGELOG.md | 12 + plugins/techdocs-react/package.json | 2 +- plugins/techdocs/CHANGELOG.md | 19 + plugins/techdocs/package.json | 2 +- plugins/todo-backend/CHANGELOG.md | 13 + plugins/todo-backend/package.json | 2 +- plugins/todo/CHANGELOG.md | 13 + plugins/todo/package.json | 2 +- plugins/user-settings-backend/CHANGELOG.md | 11 + plugins/user-settings-backend/package.json | 2 +- plugins/user-settings/CHANGELOG.md | 18 + plugins/user-settings/package.json | 2 +- plugins/vault-backend/CHANGELOG.md | 14 + plugins/vault-backend/package.json | 2 +- plugins/vault/CHANGELOG.md | 13 + plugins/vault/package.json | 2 +- plugins/xcmetrics/CHANGELOG.md | 11 + plugins/xcmetrics/package.json | 2 +- yarn.lock | 313 ++- 359 files changed, 5134 insertions(+), 189 deletions(-) create mode 100644 .changeset/create-app-1669131574.md create mode 100644 docs/releases/v1.9.0-next.0-changelog.md create mode 100644 packages/repo-tools/CHANGELOG.md diff --git a/.changeset/create-app-1669131574.md b/.changeset/create-app-1669131574.md new file mode 100644 index 0000000000..b50d431d4b --- /dev/null +++ b/.changeset/create-app-1669131574.md @@ -0,0 +1,5 @@ +--- +'@backstage/create-app': patch +--- + +Bumped create-app version. diff --git a/.changeset/pre.json b/.changeset/pre.json index 75ac96bbd7..136b807fdf 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -189,5 +189,46 @@ "@backstage/plugin-vault-backend": "0.2.4", "@backstage/plugin-xcmetrics": "0.2.31" }, - "changesets": [] + "changesets": [ + "angry-dingos-lick", + "angry-trees-relax", + "chilly-ads-lay", + "clean-paws-fry", + "clever-pillows-drive", + "clever-rivers-obey", + "create-app-1669131574", + "early-hairs-switch", + "early-parrots-guess", + "fair-walls-talk", + "fast-lies-remain", + "fluffy-walls-approve", + "four-adults-provide", + "funny-numbers-compete", + "gold-icons-cheat", + "gorgeous-hairs-applaud", + "hip-stingrays-kneel", + "itchy-walls-boil", + "modern-mugs-shout", + "new-bugs-march", + "nine-ears-whisper", + "old-keys-leave", + "renovate-3fe8460", + "renovate-4bb70f3", + "renovate-778b2fa", + "rich-garlics-play", + "search-heavy-frogs-confess", + "search-om-manniskan-ginge", + "serious-windows-occur", + "silly-wolves-remember", + "slow-dragons-promise", + "soft-nails-arrive", + "sour-flowers-care", + "sour-plums-grow", + "tender-parrots-cover", + "thin-donuts-join", + "twelve-meals-smell", + "twenty-dodos-wash", + "weak-ears-jam", + "young-turkeys-relax" + ] } diff --git a/docs/releases/v1.9.0-next.0-changelog.md b/docs/releases/v1.9.0-next.0-changelog.md new file mode 100644 index 0000000000..690bf60ceb --- /dev/null +++ b/docs/releases/v1.9.0-next.0-changelog.md @@ -0,0 +1,2305 @@ +# Release v1.9.0-next.0 + +## @backstage/catalog-client@1.2.0-next.0 + +### Minor Changes + +- 00d90b520a: **BREAKING PRODUCERS**: Added a new `getEntitiesByRefs` endpoint to `CatalogApi`, for efficient batch fetching of entities by ref. + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + +## @backstage/repo-tools@0.1.0-next.0 + +### Minor Changes + +- 99713fd671: Introducing repo-tools package + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.1.4-next.0 + +## @backstage/plugin-catalog-backend@1.6.0-next.0 + +### Minor Changes + +- 16891a212c: Added new `POST /entities/by-refs` endpoint, which allows you to efficiently + batch-fetch entities by their entity ref. This can be useful e.g. in graphql + resolvers or similar contexts where you need to fetch many entities at the same + time. + +### Patch Changes + +- d8593ce0e6: Do not use deprecated `LocationSpec` from the `@backstage/plugin-catalog-node` package +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- e982f77fe3: Registered shutdown hook in experimental catalog plugin. +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/plugin-permission-common@0.7.2-next.0 + - @backstage/plugin-permission-node@0.7.2-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + - @backstage/plugin-catalog-node@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/plugin-catalog-common@1.0.9-next.0 + - @backstage/plugin-scaffolder-common@1.2.3-next.0 + - @backstage/plugin-search-common@1.1.2-next.0 + +## @backstage/plugin-events-backend@0.2.0-next.0 + +### Minor Changes + +- cf41eedf43: **BREAKING:** Remove required field `router` at `HttpPostIngressEventPublisher.fromConfig` + and replace it with `bind(router: Router)`. + Additionally, the path prefix `/http` will be added inside `HttpPostIngressEventPublisher`. + + ```diff + // at packages/backend/src/plugins/events.ts + const eventsRouter = Router(); + - const httpRouter = Router(); + - eventsRouter.use('/http', httpRouter); + + const http = HttpPostIngressEventPublisher.fromConfig({ + config: env.config, + logger: env.logger, + - router: httpRouter, + }); + + http.bind(eventsRouter); + ``` + +### Patch Changes + +- cf41eedf43: Introduce a new interface `RequestDetails` to abstract `Request` + providing access to request body and headers. + + **BREAKING:** Replace `request: Request` with `request: RequestDetails` at `RequestValidator`. + +- Updated dependencies + - @backstage/plugin-events-node@0.2.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + - @backstage/config@1.0.5-next.0 + +## @backstage/plugin-events-node@0.2.0-next.0 + +### Minor Changes + +- cf41eedf43: Introduce a new interface `RequestDetails` to abstract `Request` + providing access to request body and headers. + + **BREAKING:** Replace `request: Request` with `request: RequestDetails` at `RequestValidator`. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.1.5-next.0 + +## @backstage/plugin-scaffolder@1.9.0-next.0 + +### Minor Changes + +- ddd1c3308d: Implement Custom Field Explorer to view and play around with available installed custom field extensions +- adb1b01e32: Adds the ability to supply a `transformErrors` function to the `Stepper` for `/next` + +### Patch Changes + +- d4d07cf55e: Enabling the customization of the last step in the scaffolder template. + + To override the content you have to do the next: + + ```typescript jsx + + ``` + +- ef803022f1: Initialize all `formData` in the `Stepper` in `/next` + +- 3280711113: Updated dependency `msw` to `^0.49.0`. + +- 19356df560: Updated dependency `zen-observable` to `^0.9.0`. + +- a63e2df559: fixed `headerOptions` not passed to `TemplatePage` component + +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration-react@1.1.7-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-common@1.0.9-next.0 + - @backstage/plugin-permission-react@0.4.8-next.0 + - @backstage/plugin-scaffolder-common@1.2.3-next.0 + +## @backstage/plugin-user-settings@0.6.0-next.0 + +### Minor Changes + +- 29bdda5442: Added the ability to fully customize settings page. Deprecated UserSettingsTab in favour of SettingsLayout.Route + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- 19356df560: Updated dependency `zen-observable` to `^0.9.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-app-api@1.2.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + +## @backstage/app-defaults@1.0.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-app-api@1.2.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-permission-react@0.4.8-next.0 + +## @backstage/backend-app-api@0.2.4-next.0 + +### Patch Changes + +- d6dbf1792b: Added `lifecycleFactory` implementation. +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/plugin-permission-node@0.7.2-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/errors@1.1.4-next.0 + +## @backstage/backend-common@0.16.1-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- dfc8edf9c5: Internal refactor to avoid usage of deprecated symbols. +- Updated dependencies + - @backstage/config-loader@1.1.7-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + +## @backstage/backend-defaults@0.1.4-next.0 + +### Patch Changes + +- d6dbf1792b: Added `lifecycleFactory` to default service factories. +- Updated dependencies + - @backstage/backend-app-api@0.2.4-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + +## @backstage/backend-plugin-api@0.1.5-next.0 + +### Patch Changes + +- d6dbf1792b: Added initial support for registering shutdown hooks via `lifecycleServiceRef`. +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/plugin-permission-common@0.7.2-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/config@1.0.5-next.0 + +## @backstage/backend-tasks@0.3.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + +## @backstage/backend-test-utils@0.1.31-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/cli@0.21.2-next.0 + - @backstage/backend-app-api@0.2.4-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + - @backstage/config@1.0.5-next.0 + +## @backstage/catalog-model@1.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.0.2-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + +## @backstage/cli@0.21.2-next.0 + +### Patch Changes + +- 91d050c140: changed tests created by create-plugin to follow eslint-rules best practices particularly testing-library/prefer-screen-queries and testing-library/render-result-naming-convention +- 459a3457e1: Bump `msw` version in default plugin/app templates +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/config-loader@1.1.7-next.0 + - @backstage/release-manifests@0.0.8-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + +## @backstage/config@1.0.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.0.2-next.0 + +## @backstage/config-loader@1.1.7-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/types@1.0.2-next.0 + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + +## @backstage/core-app-api@1.2.1-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- 19356df560: Updated dependency `zen-observable` to `^0.9.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/version-bridge@1.0.2 + +## @backstage/core-components@0.12.1-next.0 + +### Patch Changes + +- ea4a5be8f3: Create a variable for minimum height and add a prop named 'fit' for determining if the graph height should grow or be contained. +- 64a579a998: Add items prop to SupportButton. This prop can be used to override the items that would otherwise be grabbed from the config. +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- 19356df560: Updated dependency `zen-observable` to `^0.9.0`. +- 17a8e32f39: Updated dependency `rc-progress` to `3.4.1`. +- dfc8edf9c5: Internal refactor to avoid usage of deprecated symbols. +- Updated dependencies + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + - @backstage/version-bridge@1.0.2 + +## @backstage/core-plugin-api@1.1.1-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- 19356df560: Updated dependency `zen-observable` to `^0.9.0`. +- Updated dependencies + - @backstage/types@1.0.2-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/version-bridge@1.0.2 + +## @backstage/create-app@0.4.35-next.0 + +### Patch Changes + +- Bumped create-app version. +- Updated dependencies + - @backstage/cli-common@0.1.10 + +## @backstage/dev-utils@1.0.9-next.0 + +### Patch Changes + +- 19356df560: Updated dependency `zen-observable` to `^0.9.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-app-api@1.2.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration-react@1.1.7-next.0 + - @backstage/test-utils@1.2.3-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/app-defaults@1.0.9-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + +## @backstage/errors@1.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.0.2-next.0 + +## @backstage/integration@1.4.1-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- 34b039ca9f: Added `integrations.github.apps.allowedInstallationOwners` to the configuration schema. +- Updated dependencies + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + +## @backstage/integration-react@1.1.7-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/theme@0.2.16 + +## @backstage/release-manifests@0.0.8-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. + +## @techdocs/cli@1.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.5-next.0 + - @backstage/plugin-techdocs-node@1.4.3-next.0 + +## @backstage/test-utils@1.2.3-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- 19356df560: Updated dependency `zen-observable` to `^0.9.0`. +- Updated dependencies + - @backstage/core-app-api@1.2.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-permission-common@0.7.2-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-permission-react@0.4.8-next.0 + +## @backstage/types@1.0.2-next.0 + +### Patch Changes + +- 19356df560: Updated dependency `zen-observable` to `^0.9.0`. + +## @backstage/plugin-adr@0.2.4-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration-react@1.1.7-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-adr-common@0.2.4-next.0 + - @backstage/plugin-search-common@1.1.2-next.0 + - @backstage/plugin-search-react@1.2.2-next.0 + +## @backstage/plugin-adr-backend@0.2.4-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/plugin-adr-common@0.2.4-next.0 + - @backstage/plugin-search-common@1.1.2-next.0 + +## @backstage/plugin-adr-common@0.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.4.1-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/plugin-search-common@1.1.2-next.0 + +## @backstage/plugin-airbrake@0.3.12-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/test-utils@1.2.3-next.0 + - @backstage/dev-utils@1.0.9-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-airbrake-backend@0.2.12-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/config@1.0.5-next.0 + +## @backstage/plugin-allure@0.1.28-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-analytics-module-ga@0.1.23-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-apache-airflow@0.2.5-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + +## @backstage/plugin-api-docs@0.8.12-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/plugin-catalog@1.6.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-apollo-explorer@0.1.5-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-app-backend@0.3.39-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/config-loader@1.1.7-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + - @backstage/config@1.0.5-next.0 + +## @backstage/plugin-auth-backend@0.17.2-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/plugin-auth-node@0.2.8-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + +## @backstage/plugin-auth-node@0.2.8-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + +## @backstage/plugin-azure-devops@0.2.3-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-azure-devops-common@0.3.0 + +## @backstage/plugin-azure-devops-backend@0.3.18-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/plugin-azure-devops-common@0.3.0 + +## @backstage/plugin-azure-sites@0.1.1-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-azure-sites-common@0.1.0 + +## @backstage/plugin-azure-sites-backend@0.1.1-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/plugin-azure-sites-common@0.1.0 + +## @backstage/plugin-badges@0.2.36-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-badges-backend@0.1.33-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + +## @backstage/plugin-bazaar@0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/cli@0.21.2-next.0 + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/plugin-catalog@1.6.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + +## @backstage/plugin-bazaar-backend@0.2.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/backend-test-utils@0.1.31-next.0 + - @backstage/plugin-auth-node@0.2.8-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + +## @backstage/plugin-bitbucket-cloud-common@0.2.2-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/integration@1.4.1-next.0 + +## @backstage/plugin-bitrise@0.1.39-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-catalog@1.6.2-next.0 + +### Patch Changes + +- 19356df560: Updated dependency `zen-observable` to `^0.9.0`. +- 387d1d5218: Fixed Entity kind pluralisation in the `CatalogKindHeader` component. +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration-react@1.1.7-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-common@1.0.9-next.0 + - @backstage/plugin-search-common@1.1.2-next.0 + - @backstage/plugin-search-react@1.2.2-next.0 + +## @backstage/plugin-catalog-backend-module-aws@0.1.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.6.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + - @backstage/plugin-catalog-node@1.2.2-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + +## @backstage/plugin-catalog-backend-module-azure@0.1.10-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.6.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + - @backstage/plugin-catalog-node@1.2.2-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + +## @backstage/plugin-catalog-backend-module-bitbucket@0.2.6-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.6.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.2-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.1.6-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/plugin-catalog-backend@1.6.0-next.0 + - @backstage/plugin-events-node@0.2.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.2-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + - @backstage/plugin-catalog-node@1.2.2-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/plugin-catalog-common@1.0.9-next.0 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.1.4-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.6.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + - @backstage/plugin-catalog-node@1.2.2-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + +## @backstage/plugin-catalog-backend-module-gerrit@0.1.7-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.6.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + - @backstage/plugin-catalog-node@1.2.2-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + +## @backstage/plugin-catalog-backend-module-github@0.2.2-next.0 + +### Patch Changes + +- 70fa5ec3ec: Fixes the assignment of group member references in `GithubMultiOrgProcessor` so membership relations are resolved correctly. +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- 754b5854df: Fix incorrectly exported GithubOrgEntityProvider as a type +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/plugin-catalog-backend@1.6.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + - @backstage/plugin-catalog-node@1.2.2-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + +## @backstage/plugin-catalog-backend-module-gitlab@0.1.10-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.6.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + - @backstage/plugin-catalog-node@1.2.2-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + +## @backstage/plugin-catalog-backend-module-ldap@0.5.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.6.0-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + +## @backstage/plugin-catalog-backend-module-msgraph@0.4.5-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.6.0-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + - @backstage/plugin-catalog-node@1.2.2-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + +## @backstage/plugin-catalog-backend-module-openapi@0.1.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.6.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/plugin-catalog-node@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + +## @backstage/plugin-catalog-common@1.0.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/plugin-search-common@1.1.2-next.0 + +## @backstage/plugin-catalog-graph@0.2.24-next.0 + +### Patch Changes + +- cb716004ef: Internal refactor to improve tests +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-catalog-graphql@0.3.16-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/types@1.0.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + +## @backstage/plugin-catalog-import@0.9.2-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration-react@1.1.7-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/plugin-catalog-common@1.0.9-next.0 + +## @backstage/plugin-catalog-node@1.2.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/plugin-catalog-common@1.0.9-next.0 + +## @backstage/plugin-catalog-react@1.2.2-next.0 + +### Patch Changes + +- 19356df560: Updated dependency `zen-observable` to `^0.9.0`. +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/plugin-permission-common@0.7.2-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + - @backstage/version-bridge@1.0.2 + - @backstage/plugin-catalog-common@1.0.9-next.0 + - @backstage/plugin-permission-react@0.4.8-next.0 + +## @backstage/plugin-cicd-statistics@0.1.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + +## @backstage/plugin-cicd-statistics-module-gitlab@0.1.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/plugin-cicd-statistics@0.1.14-next.0 + +## @backstage/plugin-circleci@0.3.12-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-cloudbuild@0.3.12-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-code-climate@0.1.12-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-code-coverage@0.2.5-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-code-coverage-backend@0.2.5-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + +## @backstage/plugin-codescene@0.1.7-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- 17a8e32f39: Updated dependency `rc-progress` to `3.4.1`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-config-schema@0.1.35-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- 19356df560: Updated dependency `zen-observable` to `^0.9.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-cost-insights@0.12.1-next.0 + +### Patch Changes + +- f9bbb3be37: Provide the ability to change the base currency from USD to any other currency in cost insights plugin +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-cost-insights-common@0.1.1 + +## @backstage/plugin-dynatrace@1.0.2-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-events-backend-module-aws-sqs@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.2.0-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/config@1.0.5-next.0 + +## @backstage/plugin-events-backend-module-azure@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.2.0-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.2.0-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + +## @backstage/plugin-events-backend-module-gerrit@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.2.0-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + +## @backstage/plugin-events-backend-module-github@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.2.0-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + +## @backstage/plugin-events-backend-module-gitlab@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.2.0-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + +## @backstage/plugin-events-backend-test-utils@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.2.0-next.0 + +## @backstage/plugin-explore@0.3.43-next.0 + +### Patch Changes + +- ea4a5be8f3: Adds styling to graph forcing it to always fill out the available space. +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-explore-react@0.0.24-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-explore-react@0.0.24-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.1.1-next.0 + +## @backstage/plugin-firehydrant@0.1.29-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-fossa@0.2.44-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-gcalendar@0.3.8-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-gcp-projects@0.3.31-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-git-release-manager@0.3.25-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-github-actions@0.5.12-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-github-deployments@0.1.43-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration-react@1.1.7-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-github-issues@0.2.1-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-github-pull-requests-board@0.1.6-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-gitops-profiles@0.3.30-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-gocd@0.1.18-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-graphiql@0.2.44-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-graphql-backend@0.1.29-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/plugin-catalog-graphql@0.3.16-next.0 + - @backstage/config@1.0.5-next.0 + +## @backstage/plugin-home@0.4.28-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-stack-overflow@0.1.8-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-ilert@0.2.1-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-jenkins@0.7.11-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-jenkins-common@0.1.11-next.0 + +## @backstage/plugin-jenkins-backend@0.1.29-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/plugin-auth-node@0.2.8-next.0 + - @backstage/plugin-permission-common@0.7.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/plugin-jenkins-common@0.1.11-next.0 + +## @backstage/plugin-jenkins-common@0.1.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.2-next.0 + - @backstage/plugin-catalog-common@1.0.9-next.0 + +## @backstage/plugin-kafka@0.3.12-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-kafka-backend@0.2.32-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + +## @backstage/plugin-kubernetes@0.7.5-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/plugin-kubernetes-common@0.4.5-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-kubernetes-backend@0.8.1-next.0 + +### Patch Changes + +- b585179770: Added Kubernetes proxy API route to backend Kubernetes plugin, allowing Backstage plugin developers to read/write new information from Kubernetes (if proper credentials are provided). +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/backend-test-utils@0.1.31-next.0 + - @backstage/plugin-auth-node@0.2.8-next.0 + - @backstage/plugin-kubernetes-common@0.4.5-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + +## @backstage/plugin-kubernetes-common@0.4.5-next.0 + +### Patch Changes + +- b585179770: Added Kubernetes proxy API route to backend Kubernetes plugin, allowing Backstage plugin developers to read/write new information from Kubernetes (if proper credentials are provided). +- Updated dependencies + - @backstage/catalog-model@1.1.4-next.0 + +## @backstage/plugin-lighthouse@0.3.12-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-newrelic@0.3.30-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-newrelic-dashboard@0.2.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + +## @backstage/plugin-org@0.6.1-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-org-react@0.1.1-next.0 + +### Patch Changes + +- 4cb5066828: Bug fixes and adding the possibility to add a default value for the `GroupListPicker`. Fixes: Vertical size jump on text entry, left align for text, selecting a value closes the popup, auto focus on the popup when opening +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-pagerduty@0.5.5-next.0 + +### Patch Changes + +- cb716004ef: Internal refactor to improve tests +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-periskop@0.1.10-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-periskop-backend@0.1.10-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/config@1.0.5-next.0 + +## @backstage/plugin-permission-backend@0.5.14-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/plugin-auth-node@0.2.8-next.0 + - @backstage/plugin-permission-common@0.7.2-next.0 + - @backstage/plugin-permission-node@0.7.2-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + +## @backstage/plugin-permission-common@0.7.2-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/types@1.0.2-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + +## @backstage/plugin-permission-node@0.7.2-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/plugin-auth-node@0.2.8-next.0 + - @backstage/plugin-permission-common@0.7.2-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + +## @backstage/plugin-permission-react@0.4.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-permission-common@0.7.2-next.0 + - @backstage/config@1.0.5-next.0 + +## @backstage/plugin-playlist@0.1.3-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-permission-common@0.7.2-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-common@1.0.9-next.0 + - @backstage/plugin-permission-react@0.4.8-next.0 + - @backstage/plugin-playlist-common@0.1.3-next.0 + - @backstage/plugin-search-react@1.2.2-next.0 + +## @backstage/plugin-playlist-backend@0.2.2-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/backend-test-utils@0.1.31-next.0 + - @backstage/plugin-auth-node@0.2.8-next.0 + - @backstage/plugin-permission-common@0.7.2-next.0 + - @backstage/plugin-permission-node@0.7.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/plugin-playlist-common@0.1.3-next.0 + +## @backstage/plugin-playlist-common@0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.2-next.0 + +## @backstage/plugin-proxy-backend@0.2.33-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/config@1.0.5-next.0 + +## @backstage/plugin-rollbar@0.4.12-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-rollbar-backend@0.1.36-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/config@1.0.5-next.0 + +## @backstage/plugin-scaffolder-backend@1.8.1-next.0 + +### Patch Changes + +- cb716004ef: Internal refactor to improve tests +- 26404430bc: Use Json types from @backstage/types +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- 19356df560: Updated dependency `zen-observable` to `^0.9.0`. +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/plugin-catalog-backend@1.6.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/plugin-auth-node@0.2.8-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + - @backstage/plugin-catalog-node@1.2.2-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/plugin-scaffolder-common@1.2.3-next.0 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.2.14-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.8.1-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + +## @backstage/plugin-scaffolder-backend-module-rails@0.4.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.8.1-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.2.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.8.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/config@1.0.5-next.0 + +## @backstage/plugin-scaffolder-common@1.2.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.0.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + +## @backstage/plugin-search@1.0.5-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + - @backstage/version-bridge@1.0.2 + - @backstage/plugin-search-common@1.1.2-next.0 + - @backstage/plugin-search-react@1.2.2-next.0 + +## @backstage/plugin-search-backend@1.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-node@1.0.5-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/plugin-auth-node@0.2.8-next.0 + - @backstage/plugin-permission-common@0.7.2-next.0 + - @backstage/plugin-permission-node@0.7.2-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/plugin-search-common@1.1.2-next.0 + +## @backstage/plugin-search-backend-module-elasticsearch@1.0.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-node@1.0.5-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/plugin-search-common@1.1.2-next.0 + +## @backstage/plugin-search-backend-module-pg@0.4.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-node@1.0.5-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/plugin-search-common@1.1.2-next.0 + +## @backstage/plugin-search-backend-node@1.0.5-next.0 + +### Patch Changes + +- a962ce0551: Wait for indexer initialization before finalizing indexing. +- 683ced83f6: Fixed a bug that could cause a `max listeners exceeded warning` to be logged when more than 10 collators were running simultaneously. +- 81b1e7b0fe: Updated indexer and decorator base classes to take advantage of features introduced in Node.js v16; be sure you are running a [supported version of Node.js](https://backstage.io/docs/releases/v1.8.0#node-16-and-18). +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/plugin-permission-common@0.7.2-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/plugin-search-common@1.1.2-next.0 + +## @backstage/plugin-search-common@1.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.2-next.0 + - @backstage/types@1.0.2-next.0 + +## @backstage/plugin-search-react@1.2.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/theme@0.2.16 + - @backstage/version-bridge@1.0.2 + - @backstage/plugin-search-common@1.1.2-next.0 + +## @backstage/plugin-sentry@0.4.5-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-shortcuts@0.3.4-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- 19356df560: Updated dependency `zen-observable` to `^0.9.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-sonarqube@0.5.1-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- 17a8e32f39: Updated dependency `rc-progress` to `3.4.1`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-sonarqube-backend@0.1.4-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + +## @backstage/plugin-splunk-on-call@0.4.1-next.0 + +### Patch Changes + +- cb716004ef: Internal refactor to improve tests +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-stack-overflow@0.1.8-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-home@0.4.28-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-search-common@1.1.2-next.0 + +## @backstage/plugin-stack-overflow-backend@0.1.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.21.2-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/plugin-search-common@1.1.2-next.0 + +## @backstage/plugin-tech-insights@0.3.4-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-tech-insights-common@0.2.9-next.0 + +## @backstage/plugin-tech-insights-backend@0.5.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/plugin-tech-insights-common@0.2.9-next.0 + - @backstage/plugin-tech-insights-node@0.3.7-next.0 + +## @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.23-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/plugin-tech-insights-common@0.2.9-next.0 + - @backstage/plugin-tech-insights-node@0.3.7-next.0 + +## @backstage/plugin-tech-insights-common@0.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.0.2-next.0 + +## @backstage/plugin-tech-insights-node@0.3.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/plugin-tech-insights-common@0.2.9-next.0 + +## @backstage/plugin-tech-radar@0.5.19-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-techdocs@1.4.1-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/plugin-techdocs-react@1.0.7-next.0 + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration-react@1.1.7-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-search-common@1.1.2-next.0 + - @backstage/plugin-search-react@1.2.2-next.0 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.7-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/plugin-techdocs-react@1.0.7-next.0 + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-app-api@1.2.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration-react@1.1.7-next.0 + - @backstage/test-utils@1.2.3-next.0 + - @backstage/plugin-techdocs@1.4.1-next.0 + - @backstage/plugin-catalog@1.6.2-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-search-react@1.2.2-next.0 + +## @backstage/plugin-techdocs-backend@1.4.2-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/plugin-permission-common@0.7.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/plugin-catalog-common@1.0.9-next.0 + - @backstage/plugin-search-common@1.1.2-next.0 + - @backstage/plugin-techdocs-node@1.4.3-next.0 + +## @backstage/plugin-techdocs-module-addons-contrib@1.0.7-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- 8536e7c281: Use `app.title` from `app-config.yaml` when creating new Documentation Feedback issue. `Backstage` is the default value. +- Updated dependencies + - @backstage/plugin-techdocs-react@1.0.7-next.0 + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration-react@1.1.7-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-techdocs-node@1.4.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/plugin-search-common@1.1.2-next.0 + +## @backstage/plugin-techdocs-react@1.0.7-next.0 + +### Patch Changes + +- cb716004ef: Internal refactor to improve tests +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/version-bridge@1.0.2 + +## @backstage/plugin-todo@0.2.14-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-todo-backend@0.1.36-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + +## @backstage/plugin-user-settings-backend@0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/plugin-auth-node@0.2.8-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + +## @backstage/plugin-vault@0.1.6-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-vault-backend@0.2.5-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- 7a3d2688ed: Use `express-promise-router` to catch errors properly. + Add `403` error as a known one. It will now return a `NotAllowed` error. +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/backend-test-utils@0.1.31-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + +## @backstage/plugin-xcmetrics@0.2.32-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + +## example-app@0.2.78-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-graph@0.2.24-next.0 + - @backstage/plugin-pagerduty@0.5.5-next.0 + - @backstage/plugin-techdocs-react@1.0.7-next.0 + - @backstage/plugin-scaffolder@1.9.0-next.0 + - @backstage/cli@0.21.2-next.0 + - @backstage/plugin-cost-insights@0.12.1-next.0 + - @backstage/core-components@0.12.1-next.0 + - @backstage/plugin-user-settings@0.6.0-next.0 + - @backstage/plugin-explore@0.3.43-next.0 + - @backstage/core-app-api@1.2.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration-react@1.1.7-next.0 + - @backstage/plugin-airbrake@0.3.12-next.0 + - @backstage/plugin-apache-airflow@0.2.5-next.0 + - @backstage/plugin-api-docs@0.8.12-next.0 + - @backstage/plugin-azure-devops@0.2.3-next.0 + - @backstage/plugin-azure-sites@0.1.1-next.0 + - @backstage/plugin-badges@0.2.36-next.0 + - @backstage/plugin-catalog-import@0.9.2-next.0 + - @backstage/plugin-circleci@0.3.12-next.0 + - @backstage/plugin-cloudbuild@0.3.12-next.0 + - @backstage/plugin-code-coverage@0.2.5-next.0 + - @backstage/plugin-dynatrace@1.0.2-next.0 + - @backstage/plugin-gcalendar@0.3.8-next.0 + - @backstage/plugin-gcp-projects@0.3.31-next.0 + - @backstage/plugin-github-actions@0.5.12-next.0 + - @backstage/plugin-gocd@0.1.18-next.0 + - @backstage/plugin-graphiql@0.2.44-next.0 + - @backstage/plugin-home@0.4.28-next.0 + - @backstage/plugin-jenkins@0.7.11-next.0 + - @backstage/plugin-kafka@0.3.12-next.0 + - @backstage/plugin-kubernetes@0.7.5-next.0 + - @backstage/plugin-lighthouse@0.3.12-next.0 + - @backstage/plugin-newrelic@0.3.30-next.0 + - @backstage/plugin-org@0.6.1-next.0 + - @backstage/plugin-playlist@0.1.3-next.0 + - @backstage/plugin-rollbar@0.4.12-next.0 + - @backstage/plugin-search@1.0.5-next.0 + - @backstage/plugin-sentry@0.4.5-next.0 + - @backstage/plugin-shortcuts@0.3.4-next.0 + - @backstage/plugin-stack-overflow@0.1.8-next.0 + - @backstage/plugin-tech-insights@0.3.4-next.0 + - @backstage/plugin-tech-radar@0.5.19-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.0.7-next.0 + - @backstage/plugin-techdocs@1.4.1-next.0 + - @backstage/plugin-todo@0.2.14-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/app-defaults@1.0.9-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-common@1.0.9-next.0 + - @backstage/plugin-newrelic-dashboard@0.2.5-next.0 + - @backstage/plugin-permission-react@0.4.8-next.0 + - @backstage/plugin-search-common@1.1.2-next.0 + - @backstage/plugin-search-react@1.2.2-next.0 + - @internal/plugin-catalog-customized@0.0.5-next.0 + +## example-backend@0.2.78-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.8.1-next.0 + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/plugin-catalog-backend@1.6.0-next.0 + - @backstage/plugin-events-backend@0.2.0-next.0 + - @backstage/plugin-search-backend-node@1.0.5-next.0 + - @backstage/plugin-events-node@0.2.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/plugin-app-backend@0.3.39-next.0 + - @backstage/plugin-auth-backend@0.17.2-next.0 + - @backstage/plugin-auth-node@0.2.8-next.0 + - @backstage/plugin-azure-devops-backend@0.3.18-next.0 + - @backstage/plugin-azure-sites-backend@0.1.1-next.0 + - @backstage/plugin-code-coverage-backend@0.2.5-next.0 + - @backstage/plugin-graphql-backend@0.1.29-next.0 + - @backstage/plugin-jenkins-backend@0.1.29-next.0 + - @backstage/plugin-permission-backend@0.5.14-next.0 + - @backstage/plugin-permission-common@0.7.2-next.0 + - @backstage/plugin-permission-node@0.7.2-next.0 + - @backstage/plugin-playlist-backend@0.2.2-next.0 + - @backstage/plugin-proxy-backend@0.2.33-next.0 + - @backstage/plugin-rollbar-backend@0.1.36-next.0 + - @backstage/plugin-techdocs-backend@1.4.2-next.0 + - @backstage/plugin-todo-backend@0.1.36-next.0 + - @backstage/plugin-kubernetes-backend@0.8.1-next.0 + - example-app@0.2.78-next.0 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.7-next.0 + - @backstage/plugin-badges-backend@0.1.33-next.0 + - @backstage/plugin-catalog-node@1.2.2-next.0 + - @backstage/plugin-tech-insights-backend@0.5.5-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/plugin-kafka-backend@0.2.32-next.0 + - @backstage/plugin-search-backend@1.1.2-next.0 + - @backstage/plugin-search-backend-module-elasticsearch@1.0.5-next.0 + - @backstage/plugin-search-backend-module-pg@0.4.3-next.0 + - @backstage/plugin-search-common@1.1.2-next.0 + - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.23-next.0 + - @backstage/plugin-tech-insights-node@0.3.7-next.0 + +## example-backend-next@0.0.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.8.1-next.0 + - @backstage/plugin-catalog-backend@1.6.0-next.0 + - @backstage/plugin-app-backend@0.3.39-next.0 + - @backstage/backend-defaults@0.1.4-next.0 + +## techdocs-cli-embedded-app@0.2.77-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-react@1.0.7-next.0 + - @backstage/cli@0.21.2-next.0 + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-app-api@1.2.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration-react@1.1.7-next.0 + - @backstage/test-utils@1.2.3-next.0 + - @backstage/plugin-techdocs@1.4.1-next.0 + - @backstage/plugin-catalog@1.6.2-next.0 + - @backstage/app-defaults@1.0.9-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/theme@0.2.16 + +## @internal/plugin-catalog-customized@0.0.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/plugin-catalog@1.6.2-next.0 + +## @internal/plugin-todo-list@1.0.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/theme@0.2.16 + +## @internal/plugin-todo-list-backend@1.0.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/plugin-auth-node@0.2.8-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + +## @internal/plugin-todo-list-common@1.0.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.2-next.0 diff --git a/package.json b/package.json index d40e7dfbc0..2d2d5f335b 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "@types/react": "^17", "@types/react-dom": "^17" }, - "version": "1.8.0", + "version": "1.9.0-next.0", "dependencies": { "@backstage/errors": "workspace:^", "@manypkg/get-packages": "^1.1.3" diff --git a/packages/app-defaults/CHANGELOG.md b/packages/app-defaults/CHANGELOG.md index ebe8519740..ab34404847 100644 --- a/packages/app-defaults/CHANGELOG.md +++ b/packages/app-defaults/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/app-defaults +## 1.0.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-app-api@1.2.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-permission-react@0.4.8-next.0 + ## 1.0.8 ### Patch Changes diff --git a/packages/app-defaults/package.json b/packages/app-defaults/package.json index e89757d925..10cbea0824 100644 --- a/packages/app-defaults/package.json +++ b/packages/app-defaults/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/app-defaults", "description": "Provides the default wiring of a Backstage App", - "version": "1.0.8", + "version": "1.0.9-next.0", "publishConfig": { "access": "public", "main": "dist/index.esm.js", diff --git a/packages/app/CHANGELOG.md b/packages/app/CHANGELOG.md index 69860075a1..2d7cce1b6d 100644 --- a/packages/app/CHANGELOG.md +++ b/packages/app/CHANGELOG.md @@ -1,5 +1,68 @@ # example-app +## 0.2.78-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-graph@0.2.24-next.0 + - @backstage/plugin-pagerduty@0.5.5-next.0 + - @backstage/plugin-techdocs-react@1.0.7-next.0 + - @backstage/plugin-scaffolder@1.9.0-next.0 + - @backstage/cli@0.21.2-next.0 + - @backstage/plugin-cost-insights@0.12.1-next.0 + - @backstage/core-components@0.12.1-next.0 + - @backstage/plugin-user-settings@0.6.0-next.0 + - @backstage/plugin-explore@0.3.43-next.0 + - @backstage/core-app-api@1.2.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration-react@1.1.7-next.0 + - @backstage/plugin-airbrake@0.3.12-next.0 + - @backstage/plugin-apache-airflow@0.2.5-next.0 + - @backstage/plugin-api-docs@0.8.12-next.0 + - @backstage/plugin-azure-devops@0.2.3-next.0 + - @backstage/plugin-azure-sites@0.1.1-next.0 + - @backstage/plugin-badges@0.2.36-next.0 + - @backstage/plugin-catalog-import@0.9.2-next.0 + - @backstage/plugin-circleci@0.3.12-next.0 + - @backstage/plugin-cloudbuild@0.3.12-next.0 + - @backstage/plugin-code-coverage@0.2.5-next.0 + - @backstage/plugin-dynatrace@1.0.2-next.0 + - @backstage/plugin-gcalendar@0.3.8-next.0 + - @backstage/plugin-gcp-projects@0.3.31-next.0 + - @backstage/plugin-github-actions@0.5.12-next.0 + - @backstage/plugin-gocd@0.1.18-next.0 + - @backstage/plugin-graphiql@0.2.44-next.0 + - @backstage/plugin-home@0.4.28-next.0 + - @backstage/plugin-jenkins@0.7.11-next.0 + - @backstage/plugin-kafka@0.3.12-next.0 + - @backstage/plugin-kubernetes@0.7.5-next.0 + - @backstage/plugin-lighthouse@0.3.12-next.0 + - @backstage/plugin-newrelic@0.3.30-next.0 + - @backstage/plugin-org@0.6.1-next.0 + - @backstage/plugin-playlist@0.1.3-next.0 + - @backstage/plugin-rollbar@0.4.12-next.0 + - @backstage/plugin-search@1.0.5-next.0 + - @backstage/plugin-sentry@0.4.5-next.0 + - @backstage/plugin-shortcuts@0.3.4-next.0 + - @backstage/plugin-stack-overflow@0.1.8-next.0 + - @backstage/plugin-tech-insights@0.3.4-next.0 + - @backstage/plugin-tech-radar@0.5.19-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.0.7-next.0 + - @backstage/plugin-techdocs@1.4.1-next.0 + - @backstage/plugin-todo@0.2.14-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/app-defaults@1.0.9-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-common@1.0.9-next.0 + - @backstage/plugin-newrelic-dashboard@0.2.5-next.0 + - @backstage/plugin-permission-react@0.4.8-next.0 + - @backstage/plugin-search-common@1.1.2-next.0 + - @backstage/plugin-search-react@1.2.2-next.0 + - @internal/plugin-catalog-customized@0.0.5-next.0 + ## 0.2.77 ### Patch Changes diff --git a/packages/app/package.json b/packages/app/package.json index 9978a0d515..171151f843 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "example-app", - "version": "0.2.77", + "version": "0.2.78-next.0", "private": true, "backstage": { "role": "frontend" diff --git a/packages/backend-app-api/CHANGELOG.md b/packages/backend-app-api/CHANGELOG.md index 15e4a6942d..22f29c3fd2 100644 --- a/packages/backend-app-api/CHANGELOG.md +++ b/packages/backend-app-api/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/backend-app-api +## 0.2.4-next.0 + +### Patch Changes + +- d6dbf1792b: Added `lifecycleFactory` implementation. +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/plugin-permission-node@0.7.2-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/errors@1.1.4-next.0 + ## 0.2.3 ### Patch Changes diff --git a/packages/backend-app-api/package.json b/packages/backend-app-api/package.json index c25105fc6c..75517acad1 100644 --- a/packages/backend-app-api/package.json +++ b/packages/backend-app-api/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-app-api", "description": "Core API used by Backstage backend apps", - "version": "0.2.3", + "version": "0.2.4-next.0", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-common/CHANGELOG.md b/packages/backend-common/CHANGELOG.md index ca2fca26dc..66f505399d 100644 --- a/packages/backend-common/CHANGELOG.md +++ b/packages/backend-common/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/backend-common +## 0.16.1-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- dfc8edf9c5: Internal refactor to avoid usage of deprecated symbols. +- Updated dependencies + - @backstage/config-loader@1.1.7-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + ## 0.16.0 ### Minor Changes diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json index 07694f3ea6..9fadc0aeb7 100644 --- a/packages/backend-common/package.json +++ b/packages/backend-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-common", "description": "Common functionality library for Backstage backends", - "version": "0.16.0", + "version": "0.16.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-defaults/CHANGELOG.md b/packages/backend-defaults/CHANGELOG.md index 1ba1c02e1c..270e946880 100644 --- a/packages/backend-defaults/CHANGELOG.md +++ b/packages/backend-defaults/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/backend-defaults +## 0.1.4-next.0 + +### Patch Changes + +- d6dbf1792b: Added `lifecycleFactory` to default service factories. +- Updated dependencies + - @backstage/backend-app-api@0.2.4-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + ## 0.1.3 ### Patch Changes diff --git a/packages/backend-defaults/package.json b/packages/backend-defaults/package.json index 8561f3c5d3..74d0b726e5 100644 --- a/packages/backend-defaults/package.json +++ b/packages/backend-defaults/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-defaults", "description": "Backend defaults used by Backstage backend apps", - "version": "0.1.3", + "version": "0.1.4-next.0", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-next/CHANGELOG.md b/packages/backend-next/CHANGELOG.md index e117ef1120..e8957375cd 100644 --- a/packages/backend-next/CHANGELOG.md +++ b/packages/backend-next/CHANGELOG.md @@ -1,5 +1,15 @@ # example-backend-next +## 0.0.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.8.1-next.0 + - @backstage/plugin-catalog-backend@1.6.0-next.0 + - @backstage/plugin-app-backend@0.3.39-next.0 + - @backstage/backend-defaults@0.1.4-next.0 + ## 0.0.5 ### Patch Changes diff --git a/packages/backend-next/package.json b/packages/backend-next/package.json index 3219adb21f..b8b26d6e61 100644 --- a/packages/backend-next/package.json +++ b/packages/backend-next/package.json @@ -1,6 +1,6 @@ { "name": "example-backend-next", - "version": "0.0.5", + "version": "0.0.6-next.0", "main": "dist/index.cjs.js", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/backend-plugin-api/CHANGELOG.md b/packages/backend-plugin-api/CHANGELOG.md index 2a2cc35141..b33b7ec9a4 100644 --- a/packages/backend-plugin-api/CHANGELOG.md +++ b/packages/backend-plugin-api/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/backend-plugin-api +## 0.1.5-next.0 + +### Patch Changes + +- d6dbf1792b: Added initial support for registering shutdown hooks via `lifecycleServiceRef`. +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/plugin-permission-common@0.7.2-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/config@1.0.5-next.0 + ## 0.1.4 ### Patch Changes diff --git a/packages/backend-plugin-api/package.json b/packages/backend-plugin-api/package.json index 0eee8d8d2f..2e9c0aa6ec 100644 --- a/packages/backend-plugin-api/package.json +++ b/packages/backend-plugin-api/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-plugin-api", "description": "Core API used by Backstage backend plugins", - "version": "0.1.4", + "version": "0.1.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-tasks/CHANGELOG.md b/packages/backend-tasks/CHANGELOG.md index 365bcb28ad..3276c0d453 100644 --- a/packages/backend-tasks/CHANGELOG.md +++ b/packages/backend-tasks/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/backend-tasks +## 0.3.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + ## 0.3.7 ### Patch Changes diff --git a/packages/backend-tasks/package.json b/packages/backend-tasks/package.json index b28355a7d6..1e209a4d10 100644 --- a/packages/backend-tasks/package.json +++ b/packages/backend-tasks/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-tasks", "description": "Common distributed task management library for Backstage backends", - "version": "0.3.7", + "version": "0.3.8-next.0", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-test-utils/CHANGELOG.md b/packages/backend-test-utils/CHANGELOG.md index 5422015003..77de87b476 100644 --- a/packages/backend-test-utils/CHANGELOG.md +++ b/packages/backend-test-utils/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/backend-test-utils +## 0.1.31-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/cli@0.21.2-next.0 + - @backstage/backend-app-api@0.2.4-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + - @backstage/config@1.0.5-next.0 + ## 0.1.30 ### Patch Changes diff --git a/packages/backend-test-utils/package.json b/packages/backend-test-utils/package.json index b5f2113196..6dde2fe3d4 100644 --- a/packages/backend-test-utils/package.json +++ b/packages/backend-test-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-test-utils", "description": "Test helpers library for Backstage backends", - "version": "0.1.30", + "version": "0.1.31-next.0", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend/CHANGELOG.md b/packages/backend/CHANGELOG.md index 4b72814000..d30c720c73 100644 --- a/packages/backend/CHANGELOG.md +++ b/packages/backend/CHANGELOG.md @@ -1,5 +1,51 @@ # example-backend +## 0.2.78-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.8.1-next.0 + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/plugin-catalog-backend@1.6.0-next.0 + - @backstage/plugin-events-backend@0.2.0-next.0 + - @backstage/plugin-search-backend-node@1.0.5-next.0 + - @backstage/plugin-events-node@0.2.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/plugin-app-backend@0.3.39-next.0 + - @backstage/plugin-auth-backend@0.17.2-next.0 + - @backstage/plugin-auth-node@0.2.8-next.0 + - @backstage/plugin-azure-devops-backend@0.3.18-next.0 + - @backstage/plugin-azure-sites-backend@0.1.1-next.0 + - @backstage/plugin-code-coverage-backend@0.2.5-next.0 + - @backstage/plugin-graphql-backend@0.1.29-next.0 + - @backstage/plugin-jenkins-backend@0.1.29-next.0 + - @backstage/plugin-permission-backend@0.5.14-next.0 + - @backstage/plugin-permission-common@0.7.2-next.0 + - @backstage/plugin-permission-node@0.7.2-next.0 + - @backstage/plugin-playlist-backend@0.2.2-next.0 + - @backstage/plugin-proxy-backend@0.2.33-next.0 + - @backstage/plugin-rollbar-backend@0.1.36-next.0 + - @backstage/plugin-techdocs-backend@1.4.2-next.0 + - @backstage/plugin-todo-backend@0.1.36-next.0 + - @backstage/plugin-kubernetes-backend@0.8.1-next.0 + - example-app@0.2.78-next.0 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.7-next.0 + - @backstage/plugin-badges-backend@0.1.33-next.0 + - @backstage/plugin-catalog-node@1.2.2-next.0 + - @backstage/plugin-tech-insights-backend@0.5.5-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/plugin-kafka-backend@0.2.32-next.0 + - @backstage/plugin-search-backend@1.1.2-next.0 + - @backstage/plugin-search-backend-module-elasticsearch@1.0.5-next.0 + - @backstage/plugin-search-backend-module-pg@0.4.3-next.0 + - @backstage/plugin-search-common@1.1.2-next.0 + - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.23-next.0 + - @backstage/plugin-tech-insights-node@0.3.7-next.0 + ## 0.2.77 ### Patch Changes diff --git a/packages/backend/package.json b/packages/backend/package.json index 8162293228..e7d2d5d7b7 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -1,6 +1,6 @@ { "name": "example-backend", - "version": "0.2.77", + "version": "0.2.78-next.0", "main": "dist/index.cjs.js", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/catalog-client/CHANGELOG.md b/packages/catalog-client/CHANGELOG.md index ff2f42799f..71f05de695 100644 --- a/packages/catalog-client/CHANGELOG.md +++ b/packages/catalog-client/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/catalog-client +## 1.2.0-next.0 + +### Minor Changes + +- 00d90b520a: **BREAKING PRODUCERS**: Added a new `getEntitiesByRefs` endpoint to `CatalogApi`, for efficient batch fetching of entities by ref. + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + ## 1.1.2 ### Patch Changes diff --git a/packages/catalog-client/package.json b/packages/catalog-client/package.json index 3506fddf9a..6093d6a891 100644 --- a/packages/catalog-client/package.json +++ b/packages/catalog-client/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/catalog-client", "description": "An isomorphic client for the catalog backend", - "version": "1.1.2", + "version": "1.2.0-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/catalog-model/CHANGELOG.md b/packages/catalog-model/CHANGELOG.md index c9f5b8f098..0383ec3194 100644 --- a/packages/catalog-model/CHANGELOG.md +++ b/packages/catalog-model/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/catalog-model +## 1.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.0.2-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + ## 1.1.3 ### Patch Changes diff --git a/packages/catalog-model/package.json b/packages/catalog-model/package.json index 5eaed7c679..4127936c26 100644 --- a/packages/catalog-model/package.json +++ b/packages/catalog-model/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/catalog-model", "description": "Types and validators that help describe the model of a Backstage Catalog", - "version": "1.1.3", + "version": "1.1.4-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index 035e8b3d2d..8902ec60b6 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/cli +## 0.21.2-next.0 + +### Patch Changes + +- 91d050c140: changed tests created by create-plugin to follow eslint-rules best practices particularly testing-library/prefer-screen-queries and testing-library/render-result-naming-convention +- 459a3457e1: Bump `msw` version in default plugin/app templates +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/config-loader@1.1.7-next.0 + - @backstage/release-manifests@0.0.8-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + ## 0.21.0 ### Minor Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index bc40051f52..1bba3b41a9 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/cli", "description": "CLI for developing Backstage plugins and apps", - "version": "0.21.0", + "version": "0.21.2-next.0", "publishConfig": { "access": "public" }, diff --git a/packages/config-loader/CHANGELOG.md b/packages/config-loader/CHANGELOG.md index 84fa76e097..e079cb345b 100644 --- a/packages/config-loader/CHANGELOG.md +++ b/packages/config-loader/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/config-loader +## 1.1.7-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/types@1.0.2-next.0 + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + ## 1.1.6 ### Patch Changes diff --git a/packages/config-loader/package.json b/packages/config-loader/package.json index fce901f47d..0206d05f93 100644 --- a/packages/config-loader/package.json +++ b/packages/config-loader/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/config-loader", "description": "Config loading functionality used by Backstage backend, and CLI", - "version": "1.1.6", + "version": "1.1.7-next.0", "publishConfig": { "access": "public", "main": "dist/index.cjs.js", diff --git a/packages/config/CHANGELOG.md b/packages/config/CHANGELOG.md index 5523d7efc6..cc4d1571ee 100644 --- a/packages/config/CHANGELOG.md +++ b/packages/config/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/config +## 1.0.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.0.2-next.0 + ## 1.0.4 ### Patch Changes diff --git a/packages/config/package.json b/packages/config/package.json index bf322e15af..274e7f016e 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/config", "description": "Config API used by Backstage core, backend, and CLI", - "version": "1.0.4", + "version": "1.0.5-next.0", "publishConfig": { "access": "public", "main": "dist/index.cjs.js", diff --git a/packages/core-app-api/CHANGELOG.md b/packages/core-app-api/CHANGELOG.md index 6e5d88ffae..63bb4511a1 100644 --- a/packages/core-app-api/CHANGELOG.md +++ b/packages/core-app-api/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/core-app-api +## 1.2.1-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- 19356df560: Updated dependency `zen-observable` to `^0.9.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/version-bridge@1.0.2 + ## 1.2.0 ### Minor Changes diff --git a/packages/core-app-api/package.json b/packages/core-app-api/package.json index c7a0329a9f..1c15f7d6f5 100644 --- a/packages/core-app-api/package.json +++ b/packages/core-app-api/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core-app-api", "description": "Core app API used by Backstage apps", - "version": "1.2.0", + "version": "1.2.1-next.0", "publishConfig": { "access": "public", "main": "dist/index.esm.js", diff --git a/packages/core-components/CHANGELOG.md b/packages/core-components/CHANGELOG.md index dc0df7cd2b..051dc9a67d 100644 --- a/packages/core-components/CHANGELOG.md +++ b/packages/core-components/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/core-components +## 0.12.1-next.0 + +### Patch Changes + +- ea4a5be8f3: Create a variable for minimum height and add a prop named 'fit' for determining if the graph height should grow or be contained. +- 64a579a998: Add items prop to SupportButton. This prop can be used to override the items that would otherwise be grabbed from the config. +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- 19356df560: Updated dependency `zen-observable` to `^0.9.0`. +- 17a8e32f39: Updated dependency `rc-progress` to `3.4.1`. +- dfc8edf9c5: Internal refactor to avoid usage of deprecated symbols. +- Updated dependencies + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + - @backstage/version-bridge@1.0.2 + ## 0.12.0 ### Minor Changes diff --git a/packages/core-components/package.json b/packages/core-components/package.json index af46c2b859..11aebfbc0f 100644 --- a/packages/core-components/package.json +++ b/packages/core-components/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core-components", "description": "Core components used by Backstage plugins and apps", - "version": "0.12.0", + "version": "0.12.1-next.0", "publishConfig": { "access": "public", "main": "dist/index.esm.js", diff --git a/packages/core-plugin-api/CHANGELOG.md b/packages/core-plugin-api/CHANGELOG.md index 4f71c6ca3f..2704cbcb6d 100644 --- a/packages/core-plugin-api/CHANGELOG.md +++ b/packages/core-plugin-api/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/core-plugin-api +## 1.1.1-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- 19356df560: Updated dependency `zen-observable` to `^0.9.0`. +- Updated dependencies + - @backstage/types@1.0.2-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/version-bridge@1.0.2 + ## 1.1.0 ### Minor Changes diff --git a/packages/core-plugin-api/package.json b/packages/core-plugin-api/package.json index e2ae002376..56ec92b331 100644 --- a/packages/core-plugin-api/package.json +++ b/packages/core-plugin-api/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core-plugin-api", "description": "Core API used by Backstage plugins", - "version": "1.1.0", + "version": "1.1.1-next.0", "publishConfig": { "access": "public", "main": "dist/index.esm.js", diff --git a/packages/create-app/CHANGELOG.md b/packages/create-app/CHANGELOG.md index 1b44f7dc13..e3885cc0eb 100644 --- a/packages/create-app/CHANGELOG.md +++ b/packages/create-app/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/create-app +## 0.4.35-next.0 + +### Patch Changes + +- Bumped create-app version. +- Updated dependencies + - @backstage/cli-common@0.1.10 + ## 0.4.34 ### Patch Changes diff --git a/packages/create-app/package.json b/packages/create-app/package.json index fada03dc79..406517cc89 100644 --- a/packages/create-app/package.json +++ b/packages/create-app/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/create-app", "description": "A CLI that helps you create your own Backstage app", - "version": "0.4.34", + "version": "0.4.35-next.0", "publishConfig": { "access": "public" }, diff --git a/packages/dev-utils/CHANGELOG.md b/packages/dev-utils/CHANGELOG.md index f9ba61bc5b..dec04df678 100644 --- a/packages/dev-utils/CHANGELOG.md +++ b/packages/dev-utils/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/dev-utils +## 1.0.9-next.0 + +### Patch Changes + +- 19356df560: Updated dependency `zen-observable` to `^0.9.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-app-api@1.2.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration-react@1.1.7-next.0 + - @backstage/test-utils@1.2.3-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/app-defaults@1.0.9-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + ## 1.0.8 ### Patch Changes diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json index 08c2a2c305..bbffca2956 100644 --- a/packages/dev-utils/package.json +++ b/packages/dev-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/dev-utils", "description": "Utilities for developing Backstage plugins.", - "version": "1.0.8", + "version": "1.0.9-next.0", "publishConfig": { "access": "public", "main": "dist/index.esm.js", diff --git a/packages/errors/CHANGELOG.md b/packages/errors/CHANGELOG.md index c2ed34574e..7cc653877a 100644 --- a/packages/errors/CHANGELOG.md +++ b/packages/errors/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/errors +## 1.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.0.2-next.0 + ## 1.1.3 ### Patch Changes diff --git a/packages/errors/package.json b/packages/errors/package.json index 91ec9b68b1..d9d7175890 100644 --- a/packages/errors/package.json +++ b/packages/errors/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/errors", "description": "Common utilities for error handling within Backstage", - "version": "1.1.3", + "version": "1.1.4-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/integration-react/CHANGELOG.md b/packages/integration-react/CHANGELOG.md index 8b0d83db82..efbce4d4e8 100644 --- a/packages/integration-react/CHANGELOG.md +++ b/packages/integration-react/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/integration-react +## 1.1.7-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/theme@0.2.16 + ## 1.1.6 ### Patch Changes diff --git a/packages/integration-react/package.json b/packages/integration-react/package.json index e176636fd8..f448d47b03 100644 --- a/packages/integration-react/package.json +++ b/packages/integration-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/integration-react", "description": "Frontend package for managing integrations towards external systems", - "version": "1.1.6", + "version": "1.1.7-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/integration/CHANGELOG.md b/packages/integration/CHANGELOG.md index 2789af6f60..f16605e90e 100644 --- a/packages/integration/CHANGELOG.md +++ b/packages/integration/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/integration +## 1.4.1-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- 34b039ca9f: Added `integrations.github.apps.allowedInstallationOwners` to the configuration schema. +- Updated dependencies + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + ## 1.4.0 ### Minor Changes diff --git a/packages/integration/package.json b/packages/integration/package.json index 1edeb361e6..a162cd2fea 100644 --- a/packages/integration/package.json +++ b/packages/integration/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/integration", "description": "Helpers for managing integrations towards external systems", - "version": "1.4.0", + "version": "1.4.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/release-manifests/CHANGELOG.md b/packages/release-manifests/CHANGELOG.md index 148df0a1a7..e8bb4dfb07 100644 --- a/packages/release-manifests/CHANGELOG.md +++ b/packages/release-manifests/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/release-manifests +## 0.0.8-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. + ## 0.0.7 ### Patch Changes diff --git a/packages/release-manifests/package.json b/packages/release-manifests/package.json index 8b16e32991..2a53438bd2 100644 --- a/packages/release-manifests/package.json +++ b/packages/release-manifests/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/release-manifests", "description": "Helper library for receiving release manifests", - "version": "0.0.7", + "version": "0.0.8-next.0", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/repo-tools/CHANGELOG.md b/packages/repo-tools/CHANGELOG.md new file mode 100644 index 0000000000..e510cae33d --- /dev/null +++ b/packages/repo-tools/CHANGELOG.md @@ -0,0 +1,12 @@ +# @backstage/repo-tools + +## 0.1.0-next.0 + +### Minor Changes + +- 99713fd671: Introducing repo-tools package + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.1.4-next.0 diff --git a/packages/repo-tools/package.json b/packages/repo-tools/package.json index bffed77cab..60f01c1840 100644 --- a/packages/repo-tools/package.json +++ b/packages/repo-tools/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/repo-tools", "description": "CLI for Backstage repo tooling ", - "version": "0.0.0", + "version": "0.1.0-next.0", "publishConfig": { "access": "public" }, diff --git a/packages/techdocs-cli-embedded-app/CHANGELOG.md b/packages/techdocs-cli-embedded-app/CHANGELOG.md index 6308ca41ad..320388fe3a 100644 --- a/packages/techdocs-cli-embedded-app/CHANGELOG.md +++ b/packages/techdocs-cli-embedded-app/CHANGELOG.md @@ -1,5 +1,24 @@ # techdocs-cli-embedded-app +## 0.2.77-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-react@1.0.7-next.0 + - @backstage/cli@0.21.2-next.0 + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-app-api@1.2.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration-react@1.1.7-next.0 + - @backstage/test-utils@1.2.3-next.0 + - @backstage/plugin-techdocs@1.4.1-next.0 + - @backstage/plugin-catalog@1.6.2-next.0 + - @backstage/app-defaults@1.0.9-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/theme@0.2.16 + ## 0.2.76 ### Patch Changes diff --git a/packages/techdocs-cli-embedded-app/package.json b/packages/techdocs-cli-embedded-app/package.json index 03794a9363..48d905f09e 100644 --- a/packages/techdocs-cli-embedded-app/package.json +++ b/packages/techdocs-cli-embedded-app/package.json @@ -1,6 +1,6 @@ { "name": "techdocs-cli-embedded-app", - "version": "0.2.76", + "version": "0.2.77-next.0", "private": true, "backstage": { "role": "frontend" diff --git a/packages/techdocs-cli/CHANGELOG.md b/packages/techdocs-cli/CHANGELOG.md index af177189a2..fafb27aabe 100644 --- a/packages/techdocs-cli/CHANGELOG.md +++ b/packages/techdocs-cli/CHANGELOG.md @@ -1,5 +1,16 @@ # @techdocs/cli +## 1.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.5-next.0 + - @backstage/plugin-techdocs-node@1.4.3-next.0 + ## 1.2.3 ### Patch Changes diff --git a/packages/techdocs-cli/package.json b/packages/techdocs-cli/package.json index 16d9ede690..074cbe3a70 100644 --- a/packages/techdocs-cli/package.json +++ b/packages/techdocs-cli/package.json @@ -1,7 +1,7 @@ { "name": "@techdocs/cli", "description": "Utility CLI for managing TechDocs sites in Backstage.", - "version": "1.2.3", + "version": "1.2.4-next.0", "publishConfig": { "access": "public" }, diff --git a/packages/test-utils/CHANGELOG.md b/packages/test-utils/CHANGELOG.md index 051b487fda..b9010b8d94 100644 --- a/packages/test-utils/CHANGELOG.md +++ b/packages/test-utils/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/test-utils +## 1.2.3-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- 19356df560: Updated dependency `zen-observable` to `^0.9.0`. +- Updated dependencies + - @backstage/core-app-api@1.2.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-permission-common@0.7.2-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-permission-react@0.4.8-next.0 + ## 1.2.2 ### Patch Changes diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index 2b6e461167..30e1d90c18 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/test-utils", "description": "Utilities to test Backstage plugins and apps.", - "version": "1.2.2", + "version": "1.2.3-next.0", "publishConfig": { "access": "public", "main": "dist/index.esm.js", diff --git a/packages/types/CHANGELOG.md b/packages/types/CHANGELOG.md index 23a136a9da..feb23c94bc 100644 --- a/packages/types/CHANGELOG.md +++ b/packages/types/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/types +## 1.0.2-next.0 + +### Patch Changes + +- 19356df560: Updated dependency `zen-observable` to `^0.9.0`. + ## 1.0.1 ### Patch Changes diff --git a/packages/types/package.json b/packages/types/package.json index eaf2723155..30746f8aaf 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/types", "description": "Common TypeScript types used within Backstage", - "version": "1.0.1", + "version": "1.0.2-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/adr-backend/CHANGELOG.md b/plugins/adr-backend/CHANGELOG.md index d63b5909a6..90c7de923f 100644 --- a/plugins/adr-backend/CHANGELOG.md +++ b/plugins/adr-backend/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-adr-backend +## 0.2.4-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/plugin-adr-common@0.2.4-next.0 + - @backstage/plugin-search-common@1.1.2-next.0 + ## 0.2.3 ### Patch Changes diff --git a/plugins/adr-backend/package.json b/plugins/adr-backend/package.json index 7f36529dd8..b70c2f75b4 100644 --- a/plugins/adr-backend/package.json +++ b/plugins/adr-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-adr-backend", - "version": "0.2.3", + "version": "0.2.4-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/adr-common/CHANGELOG.md b/plugins/adr-common/CHANGELOG.md index fb97b9bcaf..68f9e933c1 100644 --- a/plugins/adr-common/CHANGELOG.md +++ b/plugins/adr-common/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-adr-common +## 0.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.4.1-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/plugin-search-common@1.1.2-next.0 + ## 0.2.3 ### Patch Changes diff --git a/plugins/adr-common/package.json b/plugins/adr-common/package.json index 2ed4532a15..6ea87571d6 100644 --- a/plugins/adr-common/package.json +++ b/plugins/adr-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-adr-common", "description": "Common functionalities for the adr plugin", - "version": "0.2.3", + "version": "0.2.4-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/adr/CHANGELOG.md b/plugins/adr/CHANGELOG.md index e18d2695ba..de75bc6343 100644 --- a/plugins/adr/CHANGELOG.md +++ b/plugins/adr/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-adr +## 0.2.4-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration-react@1.1.7-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-adr-common@0.2.4-next.0 + - @backstage/plugin-search-common@1.1.2-next.0 + - @backstage/plugin-search-react@1.2.2-next.0 + ## 0.2.3 ### Patch Changes diff --git a/plugins/adr/package.json b/plugins/adr/package.json index cb490930e2..40e2c2dc0e 100644 --- a/plugins/adr/package.json +++ b/plugins/adr/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-adr", - "version": "0.2.3", + "version": "0.2.4-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/airbrake-backend/CHANGELOG.md b/plugins/airbrake-backend/CHANGELOG.md index 4cd5d7ea5b..ec05c2490a 100644 --- a/plugins/airbrake-backend/CHANGELOG.md +++ b/plugins/airbrake-backend/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-airbrake-backend +## 0.2.12-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/config@1.0.5-next.0 + ## 0.2.11 ### Patch Changes diff --git a/plugins/airbrake-backend/package.json b/plugins/airbrake-backend/package.json index 16fa8e87e3..d7b988ca3a 100644 --- a/plugins/airbrake-backend/package.json +++ b/plugins/airbrake-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-airbrake-backend", - "version": "0.2.11", + "version": "0.2.12-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/airbrake/CHANGELOG.md b/plugins/airbrake/CHANGELOG.md index b9f61927b2..e3567f8914 100644 --- a/plugins/airbrake/CHANGELOG.md +++ b/plugins/airbrake/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-airbrake +## 0.3.12-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/test-utils@1.2.3-next.0 + - @backstage/dev-utils@1.0.9-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + ## 0.3.11 ### Patch Changes diff --git a/plugins/airbrake/package.json b/plugins/airbrake/package.json index 8a3b0e5d6c..3d0c7e0050 100644 --- a/plugins/airbrake/package.json +++ b/plugins/airbrake/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-airbrake", - "version": "0.3.11", + "version": "0.3.12-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/allure/CHANGELOG.md b/plugins/allure/CHANGELOG.md index 09663e7363..cfce4f4918 100644 --- a/plugins/allure/CHANGELOG.md +++ b/plugins/allure/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-allure +## 0.1.28-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + ## 0.1.27 ### Patch Changes diff --git a/plugins/allure/package.json b/plugins/allure/package.json index 63de535c45..a83baef5d9 100644 --- a/plugins/allure/package.json +++ b/plugins/allure/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-allure", "description": "A Backstage plugin that integrates with Allure", - "version": "0.1.27", + "version": "0.1.28-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/analytics-module-ga/CHANGELOG.md b/plugins/analytics-module-ga/CHANGELOG.md index 96a16a46f5..f050e0c40b 100644 --- a/plugins/analytics-module-ga/CHANGELOG.md +++ b/plugins/analytics-module-ga/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-analytics-module-ga +## 0.1.23-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/theme@0.2.16 + ## 0.1.22 ### Patch Changes diff --git a/plugins/analytics-module-ga/package.json b/plugins/analytics-module-ga/package.json index fc225d5a72..3219e45f97 100644 --- a/plugins/analytics-module-ga/package.json +++ b/plugins/analytics-module-ga/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-analytics-module-ga", - "version": "0.1.22", + "version": "0.1.23-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/apache-airflow/CHANGELOG.md b/plugins/apache-airflow/CHANGELOG.md index a1845e0030..6d956ad4c7 100644 --- a/plugins/apache-airflow/CHANGELOG.md +++ b/plugins/apache-airflow/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-apache-airflow +## 0.2.5-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + ## 0.2.4 ### Patch Changes diff --git a/plugins/apache-airflow/package.json b/plugins/apache-airflow/package.json index d510e0e561..7d2986dbf0 100644 --- a/plugins/apache-airflow/package.json +++ b/plugins/apache-airflow/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-apache-airflow", - "version": "0.2.4", + "version": "0.2.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/api-docs/CHANGELOG.md b/plugins/api-docs/CHANGELOG.md index b340f3712e..cfcd72bf44 100644 --- a/plugins/api-docs/CHANGELOG.md +++ b/plugins/api-docs/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-api-docs +## 0.8.12-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/plugin-catalog@1.6.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + ## 0.8.11 ### Patch Changes diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json index ac0a1f9a88..66b7667a80 100644 --- a/plugins/api-docs/package.json +++ b/plugins/api-docs/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-api-docs", "description": "A Backstage plugin that helps represent API entities in the frontend", - "version": "0.8.11", + "version": "0.8.12-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/apollo-explorer/CHANGELOG.md b/plugins/apollo-explorer/CHANGELOG.md index e5d8786870..6187cef62e 100644 --- a/plugins/apollo-explorer/CHANGELOG.md +++ b/plugins/apollo-explorer/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-apollo-explorer +## 0.1.5-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/theme@0.2.16 + ## 0.1.4 ### Patch Changes diff --git a/plugins/apollo-explorer/package.json b/plugins/apollo-explorer/package.json index f302ad10f7..47a5ce74ca 100644 --- a/plugins/apollo-explorer/package.json +++ b/plugins/apollo-explorer/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-apollo-explorer", - "version": "0.1.4", + "version": "0.1.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/app-backend/CHANGELOG.md b/plugins/app-backend/CHANGELOG.md index f08415c4fb..c3dffbfd58 100644 --- a/plugins/app-backend/CHANGELOG.md +++ b/plugins/app-backend/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-app-backend +## 0.3.39-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/config-loader@1.1.7-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + - @backstage/config@1.0.5-next.0 + ## 0.3.38 ### Patch Changes diff --git a/plugins/app-backend/package.json b/plugins/app-backend/package.json index 7fe9af0cc1..2575f7e316 100644 --- a/plugins/app-backend/package.json +++ b/plugins/app-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-app-backend", "description": "A Backstage backend plugin that serves the Backstage frontend app", - "version": "0.3.38", + "version": "0.3.39-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-backend/CHANGELOG.md b/plugins/auth-backend/CHANGELOG.md index a89be139f1..9e2ff2a229 100644 --- a/plugins/auth-backend/CHANGELOG.md +++ b/plugins/auth-backend/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-auth-backend +## 0.17.2-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/plugin-auth-node@0.2.8-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + ## 0.17.1 ### Patch Changes diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json index 1b6415c3d9..6d811e84f1 100644 --- a/plugins/auth-backend/package.json +++ b/plugins/auth-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend", "description": "A Backstage backend plugin that handles authentication", - "version": "0.17.1", + "version": "0.17.2-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-node/CHANGELOG.md b/plugins/auth-node/CHANGELOG.md index 79bcabe134..a94171bd73 100644 --- a/plugins/auth-node/CHANGELOG.md +++ b/plugins/auth-node/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-auth-node +## 0.2.8-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + ## 0.2.7 ### Patch Changes diff --git a/plugins/auth-node/package.json b/plugins/auth-node/package.json index 3dffd1479a..d62794090e 100644 --- a/plugins/auth-node/package.json +++ b/plugins/auth-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-node", - "version": "0.2.7", + "version": "0.2.8-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/azure-devops-backend/CHANGELOG.md b/plugins/azure-devops-backend/CHANGELOG.md index 3f5c5bbca5..d68a5aa89f 100644 --- a/plugins/azure-devops-backend/CHANGELOG.md +++ b/plugins/azure-devops-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-azure-devops-backend +## 0.3.18-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/plugin-azure-devops-common@0.3.0 + ## 0.3.17 ### Patch Changes diff --git a/plugins/azure-devops-backend/package.json b/plugins/azure-devops-backend/package.json index c1224f2d5a..61ae636c69 100644 --- a/plugins/azure-devops-backend/package.json +++ b/plugins/azure-devops-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-azure-devops-backend", - "version": "0.3.17", + "version": "0.3.18-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/azure-devops/CHANGELOG.md b/plugins/azure-devops/CHANGELOG.md index 3eb99ef36f..76ad3f170f 100644 --- a/plugins/azure-devops/CHANGELOG.md +++ b/plugins/azure-devops/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-azure-devops +## 0.2.3-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-azure-devops-common@0.3.0 + ## 0.2.2 ### Patch Changes diff --git a/plugins/azure-devops/package.json b/plugins/azure-devops/package.json index e702f7145b..e3a735b565 100644 --- a/plugins/azure-devops/package.json +++ b/plugins/azure-devops/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-azure-devops", - "version": "0.2.2", + "version": "0.2.3-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/azure-sites-backend/CHANGELOG.md b/plugins/azure-sites-backend/CHANGELOG.md index 27d237d786..7a3a1b7be1 100644 --- a/plugins/azure-sites-backend/CHANGELOG.md +++ b/plugins/azure-sites-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-azure-sites-backend +## 0.1.1-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/plugin-azure-sites-common@0.1.0 + ## 0.1.0 ### Minor Changes diff --git a/plugins/azure-sites-backend/package.json b/plugins/azure-sites-backend/package.json index 708a919cd1..5e88a910dd 100644 --- a/plugins/azure-sites-backend/package.json +++ b/plugins/azure-sites-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-azure-sites-backend", - "version": "0.1.0", + "version": "0.1.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/azure-sites/CHANGELOG.md b/plugins/azure-sites/CHANGELOG.md index 40bc2a2107..2cc3cedb1c 100644 --- a/plugins/azure-sites/CHANGELOG.md +++ b/plugins/azure-sites/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-azure-sites +## 0.1.1-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-azure-sites-common@0.1.0 + ## 0.1.0 ### Minor Changes diff --git a/plugins/azure-sites/package.json b/plugins/azure-sites/package.json index 9378c3c702..aaf9218ec0 100644 --- a/plugins/azure-sites/package.json +++ b/plugins/azure-sites/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-azure-sites", - "version": "0.1.0", + "version": "0.1.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/badges-backend/CHANGELOG.md b/plugins/badges-backend/CHANGELOG.md index 009a0a63b6..1153ed1436 100644 --- a/plugins/badges-backend/CHANGELOG.md +++ b/plugins/badges-backend/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-badges-backend +## 0.1.33-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + ## 0.1.32 ### Patch Changes diff --git a/plugins/badges-backend/package.json b/plugins/badges-backend/package.json index b4f83b2ab6..9863578b50 100644 --- a/plugins/badges-backend/package.json +++ b/plugins/badges-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-badges-backend", "description": "A Backstage backend plugin that generates README badges for your entities", - "version": "0.1.32", + "version": "0.1.33-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/badges/CHANGELOG.md b/plugins/badges/CHANGELOG.md index 65528d8934..bdfa1b2c6f 100644 --- a/plugins/badges/CHANGELOG.md +++ b/plugins/badges/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-badges +## 0.2.36-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + ## 0.2.35 ### Patch Changes diff --git a/plugins/badges/package.json b/plugins/badges/package.json index 252d044913..9bbaa42792 100644 --- a/plugins/badges/package.json +++ b/plugins/badges/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-badges", "description": "A Backstage plugin that generates README badges for your entities", - "version": "0.2.35", + "version": "0.2.36-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/bazaar-backend/CHANGELOG.md b/plugins/bazaar-backend/CHANGELOG.md index 64f55c9e7a..43f0e70e90 100644 --- a/plugins/bazaar-backend/CHANGELOG.md +++ b/plugins/bazaar-backend/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-bazaar-backend +## 0.2.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/backend-test-utils@0.1.31-next.0 + - @backstage/plugin-auth-node@0.2.8-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + ## 0.2.1 ### Patch Changes diff --git a/plugins/bazaar-backend/package.json b/plugins/bazaar-backend/package.json index 9441d9155c..c580aa3c5f 100644 --- a/plugins/bazaar-backend/package.json +++ b/plugins/bazaar-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-bazaar-backend", - "version": "0.2.1", + "version": "0.2.2-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/bazaar/CHANGELOG.md b/plugins/bazaar/CHANGELOG.md index 20db63abe7..16056481ad 100644 --- a/plugins/bazaar/CHANGELOG.md +++ b/plugins/bazaar/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-bazaar +## 0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/cli@0.21.2-next.0 + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/plugin-catalog@1.6.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + ## 0.2.0 ### Minor Changes diff --git a/plugins/bazaar/package.json b/plugins/bazaar/package.json index 259f2bae14..54c4de670e 100644 --- a/plugins/bazaar/package.json +++ b/plugins/bazaar/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-bazaar", - "version": "0.2.0", + "version": "0.2.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/bitbucket-cloud-common/CHANGELOG.md b/plugins/bitbucket-cloud-common/CHANGELOG.md index 413d23e509..e4f0c378d4 100644 --- a/plugins/bitbucket-cloud-common/CHANGELOG.md +++ b/plugins/bitbucket-cloud-common/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-bitbucket-cloud-common +## 0.2.2-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/integration@1.4.1-next.0 + ## 0.2.1 ### Patch Changes diff --git a/plugins/bitbucket-cloud-common/package.json b/plugins/bitbucket-cloud-common/package.json index dcc558941b..3525bf9a86 100644 --- a/plugins/bitbucket-cloud-common/package.json +++ b/plugins/bitbucket-cloud-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-bitbucket-cloud-common", "description": "Common functionalities for bitbucket-cloud plugins", - "version": "0.2.1", + "version": "0.2.2-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/bitrise/CHANGELOG.md b/plugins/bitrise/CHANGELOG.md index 3a950d33d0..197abb1407 100644 --- a/plugins/bitrise/CHANGELOG.md +++ b/plugins/bitrise/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-bitrise +## 0.1.39-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + ## 0.1.38 ### Patch Changes diff --git a/plugins/bitrise/package.json b/plugins/bitrise/package.json index 67c212137d..d99340c7c3 100644 --- a/plugins/bitrise/package.json +++ b/plugins/bitrise/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-bitrise", "description": "A Backstage plugin that integrates towards Bitrise", - "version": "0.1.38", + "version": "0.1.39-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-aws/CHANGELOG.md b/plugins/catalog-backend-module-aws/CHANGELOG.md index 48ff05053d..21f146b562 100644 --- a/plugins/catalog-backend-module-aws/CHANGELOG.md +++ b/plugins/catalog-backend-module-aws/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-catalog-backend-module-aws +## 0.1.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.6.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + - @backstage/plugin-catalog-node@1.2.2-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + ## 0.1.11 ### Patch Changes diff --git a/plugins/catalog-backend-module-aws/package.json b/plugins/catalog-backend-module-aws/package.json index 5723841562..293b43da45 100644 --- a/plugins/catalog-backend-module-aws/package.json +++ b/plugins/catalog-backend-module-aws/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-aws", "description": "A Backstage catalog backend module that helps integrate towards AWS", - "version": "0.1.11", + "version": "0.1.12-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-azure/CHANGELOG.md b/plugins/catalog-backend-module-azure/CHANGELOG.md index 5e67f292b4..54b3cfc2c6 100644 --- a/plugins/catalog-backend-module-azure/CHANGELOG.md +++ b/plugins/catalog-backend-module-azure/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-catalog-backend-module-azure +## 0.1.10-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.6.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + - @backstage/plugin-catalog-node@1.2.2-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + ## 0.1.9 ### Patch Changes diff --git a/plugins/catalog-backend-module-azure/package.json b/plugins/catalog-backend-module-azure/package.json index d4d014b059..d1347f74c5 100644 --- a/plugins/catalog-backend-module-azure/package.json +++ b/plugins/catalog-backend-module-azure/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-azure", "description": "A Backstage catalog backend module that helps integrate towards Azure", - "version": "0.1.9", + "version": "0.1.10-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md index c2a83050ad..5f74571373 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-catalog-backend-module-bitbucket-cloud +## 0.1.6-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/plugin-catalog-backend@1.6.0-next.0 + - @backstage/plugin-events-node@0.2.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.2-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + - @backstage/plugin-catalog-node@1.2.2-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/plugin-catalog-common@1.0.9-next.0 + ## 0.1.5 ### Patch Changes diff --git a/plugins/catalog-backend-module-bitbucket-cloud/package.json b/plugins/catalog-backend-module-bitbucket-cloud/package.json index 14bef29eb9..f4d542f843 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/package.json +++ b/plugins/catalog-backend-module-bitbucket-cloud/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-bitbucket-cloud", "description": "A Backstage catalog backend module that helps integrate towards Bitbucket Cloud", - "version": "0.1.5", + "version": "0.1.6-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md index dbc8f168e5..8a8322fc05 100644 --- a/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-catalog-backend-module-bitbucket-server +## 0.1.4-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.6.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + - @backstage/plugin-catalog-node@1.2.2-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + ## 0.1.3 ### Patch Changes diff --git a/plugins/catalog-backend-module-bitbucket-server/package.json b/plugins/catalog-backend-module-bitbucket-server/package.json index 9a864035b5..162214b9a7 100644 --- a/plugins/catalog-backend-module-bitbucket-server/package.json +++ b/plugins/catalog-backend-module-bitbucket-server/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-bitbucket-server", - "version": "0.1.3", + "version": "0.1.4-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-bitbucket/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket/CHANGELOG.md index 774596c16f..26299b4bbe 100644 --- a/plugins/catalog-backend-module-bitbucket/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-catalog-backend-module-bitbucket +## 0.2.6-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.6.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.2-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + ## 0.2.5 ### Patch Changes diff --git a/plugins/catalog-backend-module-bitbucket/package.json b/plugins/catalog-backend-module-bitbucket/package.json index 8818bef2f3..445d5d9d3a 100644 --- a/plugins/catalog-backend-module-bitbucket/package.json +++ b/plugins/catalog-backend-module-bitbucket/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-bitbucket", "description": "A Backstage catalog backend module that helps integrate towards Bitbucket", - "version": "0.2.5", + "version": "0.2.6-next.0", "deprecated": true, "main": "src/index.ts", "types": "src/index.ts", diff --git a/plugins/catalog-backend-module-gerrit/CHANGELOG.md b/plugins/catalog-backend-module-gerrit/CHANGELOG.md index a2d9fbd8ae..7a98fd672d 100644 --- a/plugins/catalog-backend-module-gerrit/CHANGELOG.md +++ b/plugins/catalog-backend-module-gerrit/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-catalog-backend-module-gerrit +## 0.1.7-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.6.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + - @backstage/plugin-catalog-node@1.2.2-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + ## 0.1.6 ### Patch Changes diff --git a/plugins/catalog-backend-module-gerrit/package.json b/plugins/catalog-backend-module-gerrit/package.json index 2524cf54dc..3801e104d8 100644 --- a/plugins/catalog-backend-module-gerrit/package.json +++ b/plugins/catalog-backend-module-gerrit/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-gerrit", - "version": "0.1.6", + "version": "0.1.7-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-github/CHANGELOG.md b/plugins/catalog-backend-module-github/CHANGELOG.md index 6630fc2052..cf4e6d4f10 100644 --- a/plugins/catalog-backend-module-github/CHANGELOG.md +++ b/plugins/catalog-backend-module-github/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/plugin-catalog-backend-module-github +## 0.2.2-next.0 + +### Patch Changes + +- 70fa5ec3ec: Fixes the assignment of group member references in `GithubMultiOrgProcessor` so membership relations are resolved correctly. +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- 754b5854df: Fix incorrectly exported GithubOrgEntityProvider as a type +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/plugin-catalog-backend@1.6.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + - @backstage/plugin-catalog-node@1.2.2-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + ## 0.2.0 ### Minor Changes diff --git a/plugins/catalog-backend-module-github/package.json b/plugins/catalog-backend-module-github/package.json index d252e70fb9..d6d996068e 100644 --- a/plugins/catalog-backend-module-github/package.json +++ b/plugins/catalog-backend-module-github/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-github", "description": "A Backstage catalog backend module that helps integrate towards GitHub", - "version": "0.2.0", + "version": "0.2.2-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-gitlab/CHANGELOG.md b/plugins/catalog-backend-module-gitlab/CHANGELOG.md index 3eed702b41..4a05021ba9 100644 --- a/plugins/catalog-backend-module-gitlab/CHANGELOG.md +++ b/plugins/catalog-backend-module-gitlab/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-catalog-backend-module-gitlab +## 0.1.10-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.6.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + - @backstage/plugin-catalog-node@1.2.2-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + ## 0.1.9 ### Patch Changes diff --git a/plugins/catalog-backend-module-gitlab/package.json b/plugins/catalog-backend-module-gitlab/package.json index 923ebee8a0..30bb37d8e3 100644 --- a/plugins/catalog-backend-module-gitlab/package.json +++ b/plugins/catalog-backend-module-gitlab/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-gitlab", "description": "A Backstage catalog backend module that helps integrate towards GitLab", - "version": "0.1.9", + "version": "0.1.10-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-ldap/CHANGELOG.md b/plugins/catalog-backend-module-ldap/CHANGELOG.md index 19c1811c7c..495b405511 100644 --- a/plugins/catalog-backend-module-ldap/CHANGELOG.md +++ b/plugins/catalog-backend-module-ldap/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-catalog-backend-module-ldap +## 0.5.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.6.0-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + ## 0.5.5 ### Patch Changes diff --git a/plugins/catalog-backend-module-ldap/package.json b/plugins/catalog-backend-module-ldap/package.json index 2afdd4984c..a40ff4dd17 100644 --- a/plugins/catalog-backend-module-ldap/package.json +++ b/plugins/catalog-backend-module-ldap/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-ldap", "description": "A Backstage catalog backend module that helps integrate towards LDAP", - "version": "0.5.5", + "version": "0.5.6-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-msgraph/CHANGELOG.md b/plugins/catalog-backend-module-msgraph/CHANGELOG.md index 92182202a7..3e0de34927 100644 --- a/plugins/catalog-backend-module-msgraph/CHANGELOG.md +++ b/plugins/catalog-backend-module-msgraph/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend-module-msgraph +## 0.4.5-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.6.0-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + - @backstage/plugin-catalog-node@1.2.2-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + ## 0.4.4 ### Patch Changes diff --git a/plugins/catalog-backend-module-msgraph/package.json b/plugins/catalog-backend-module-msgraph/package.json index e744671809..75a5beee56 100644 --- a/plugins/catalog-backend-module-msgraph/package.json +++ b/plugins/catalog-backend-module-msgraph/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-msgraph", "description": "A Backstage catalog backend module that helps integrate towards Microsoft Graph", - "version": "0.4.4", + "version": "0.4.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-openapi/CHANGELOG.md b/plugins/catalog-backend-module-openapi/CHANGELOG.md index 519efcc45d..b16946fd7a 100644 --- a/plugins/catalog-backend-module-openapi/CHANGELOG.md +++ b/plugins/catalog-backend-module-openapi/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend-module-openapi +## 0.1.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.6.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/plugin-catalog-node@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + ## 0.1.4 ### Patch Changes diff --git a/plugins/catalog-backend-module-openapi/package.json b/plugins/catalog-backend-module-openapi/package.json index 1055b5ea92..c776573a96 100644 --- a/plugins/catalog-backend-module-openapi/package.json +++ b/plugins/catalog-backend-module-openapi/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-openapi", "description": "A Backstage catalog backend module that helps with OpenAPI specifications", - "version": "0.1.4", + "version": "0.1.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend/CHANGELOG.md b/plugins/catalog-backend/CHANGELOG.md index 75913bdf52..4354b0b7b4 100644 --- a/plugins/catalog-backend/CHANGELOG.md +++ b/plugins/catalog-backend/CHANGELOG.md @@ -1,5 +1,35 @@ # @backstage/plugin-catalog-backend +## 1.6.0-next.0 + +### Minor Changes + +- 16891a212c: Added new `POST /entities/by-refs` endpoint, which allows you to efficiently + batch-fetch entities by their entity ref. This can be useful e.g. in graphql + resolvers or similar contexts where you need to fetch many entities at the same + time. + +### Patch Changes + +- d8593ce0e6: Do not use deprecated `LocationSpec` from the `@backstage/plugin-catalog-node` package +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- e982f77fe3: Registered shutdown hook in experimental catalog plugin. +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/plugin-permission-common@0.7.2-next.0 + - @backstage/plugin-permission-node@0.7.2-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + - @backstage/plugin-catalog-node@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/plugin-catalog-common@1.0.9-next.0 + - @backstage/plugin-scaffolder-common@1.2.3-next.0 + - @backstage/plugin-search-common@1.1.2-next.0 + ## 1.5.1 ### Patch Changes diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index c999660490..ea61ca648e 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend", "description": "The Backstage backend plugin that provides the Backstage catalog", - "version": "1.5.1", + "version": "1.6.0-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-common/CHANGELOG.md b/plugins/catalog-common/CHANGELOG.md index ac236e1999..e6774acf35 100644 --- a/plugins/catalog-common/CHANGELOG.md +++ b/plugins/catalog-common/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-catalog-common +## 1.0.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/plugin-search-common@1.1.2-next.0 + ## 1.0.8 ### Patch Changes diff --git a/plugins/catalog-common/package.json b/plugins/catalog-common/package.json index 5dcbc678b2..29a525dc10 100644 --- a/plugins/catalog-common/package.json +++ b/plugins/catalog-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-common", "description": "Common functionalities for the catalog plugin", - "version": "1.0.8", + "version": "1.0.9-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-customized/CHANGELOG.md b/plugins/catalog-customized/CHANGELOG.md index 92c8a6e60f..57cd9dc8a0 100644 --- a/plugins/catalog-customized/CHANGELOG.md +++ b/plugins/catalog-customized/CHANGELOG.md @@ -1,5 +1,13 @@ # @internal/plugin-catalog-customized +## 0.0.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/plugin-catalog@1.6.2-next.0 + ## 0.0.4 ### Patch Changes diff --git a/plugins/catalog-customized/package.json b/plugins/catalog-customized/package.json index f302c48bf5..bde12058ae 100644 --- a/plugins/catalog-customized/package.json +++ b/plugins/catalog-customized/package.json @@ -1,7 +1,7 @@ { "name": "@internal/plugin-catalog-customized", "description": "The internal Backstage Customizable plugin for browsing the Backstage catalog", - "version": "0.0.4", + "version": "0.0.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-graph/CHANGELOG.md b/plugins/catalog-graph/CHANGELOG.md index 29fa300e18..75373b040c 100644 --- a/plugins/catalog-graph/CHANGELOG.md +++ b/plugins/catalog-graph/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-graph +## 0.2.24-next.0 + +### Patch Changes + +- cb716004ef: Internal refactor to improve tests +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + ## 0.2.23 ### Patch Changes diff --git a/plugins/catalog-graph/package.json b/plugins/catalog-graph/package.json index 3216efb0ec..5e47890e75 100644 --- a/plugins/catalog-graph/package.json +++ b/plugins/catalog-graph/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-graph", - "version": "0.2.23", + "version": "0.2.24-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-graphql/CHANGELOG.md b/plugins/catalog-graphql/CHANGELOG.md index 8f62b9f528..da1abff0d7 100644 --- a/plugins/catalog-graphql/CHANGELOG.md +++ b/plugins/catalog-graphql/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-catalog-graphql +## 0.3.16-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/types@1.0.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + ## 0.3.15 ### Patch Changes diff --git a/plugins/catalog-graphql/package.json b/plugins/catalog-graphql/package.json index 021289529f..735d6aa25d 100644 --- a/plugins/catalog-graphql/package.json +++ b/plugins/catalog-graphql/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-graphql", "description": "An experimental Backstage catalog GraphQL module", - "version": "0.3.15", + "version": "0.3.16-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-import/CHANGELOG.md b/plugins/catalog-import/CHANGELOG.md index 2f3bd8b9bf..884080bb03 100644 --- a/plugins/catalog-import/CHANGELOG.md +++ b/plugins/catalog-import/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-catalog-import +## 0.9.2-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration-react@1.1.7-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/plugin-catalog-common@1.0.9-next.0 + ## 0.9.1 ### Patch Changes diff --git a/plugins/catalog-import/package.json b/plugins/catalog-import/package.json index 6dae97c9d6..71e5034443 100644 --- a/plugins/catalog-import/package.json +++ b/plugins/catalog-import/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-import", "description": "A Backstage plugin the helps you import entities into your catalog", - "version": "0.9.1", + "version": "0.9.2-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-node/CHANGELOG.md b/plugins/catalog-node/CHANGELOG.md index e263ff5e87..ac31e15535 100644 --- a/plugins/catalog-node/CHANGELOG.md +++ b/plugins/catalog-node/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-catalog-node +## 1.2.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/plugin-catalog-common@1.0.9-next.0 + ## 1.2.1 ### Patch Changes diff --git a/plugins/catalog-node/package.json b/plugins/catalog-node/package.json index 09dbdd3d79..3d426998b6 100644 --- a/plugins/catalog-node/package.json +++ b/plugins/catalog-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-node", "description": "The plugin-catalog-node module for @backstage/plugin-catalog-backend", - "version": "1.2.1", + "version": "1.2.2-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-react/CHANGELOG.md b/plugins/catalog-react/CHANGELOG.md index 8eda35598f..52247c1c3e 100644 --- a/plugins/catalog-react/CHANGELOG.md +++ b/plugins/catalog-react/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-catalog-react +## 1.2.2-next.0 + +### Patch Changes + +- 19356df560: Updated dependency `zen-observable` to `^0.9.0`. +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/plugin-permission-common@0.7.2-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + - @backstage/version-bridge@1.0.2 + - @backstage/plugin-catalog-common@1.0.9-next.0 + - @backstage/plugin-permission-react@0.4.8-next.0 + ## 1.2.1 ### Patch Changes diff --git a/plugins/catalog-react/package.json b/plugins/catalog-react/package.json index b4e40d8546..b3a39b8397 100644 --- a/plugins/catalog-react/package.json +++ b/plugins/catalog-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-react", "description": "A frontend library that helps other Backstage plugins interact with the catalog", - "version": "1.2.1", + "version": "1.2.2-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog/CHANGELOG.md b/plugins/catalog/CHANGELOG.md index 99ece53655..b5d431fdb1 100644 --- a/plugins/catalog/CHANGELOG.md +++ b/plugins/catalog/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/plugin-catalog +## 1.6.2-next.0 + +### Patch Changes + +- 19356df560: Updated dependency `zen-observable` to `^0.9.0`. +- 387d1d5218: Fixed Entity kind pluralisation in the `CatalogKindHeader` component. +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration-react@1.1.7-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-common@1.0.9-next.0 + - @backstage/plugin-search-common@1.1.2-next.0 + - @backstage/plugin-search-react@1.2.2-next.0 + ## 1.6.1 ### Patch Changes diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json index 244aab8626..697a3924a4 100644 --- a/plugins/catalog/package.json +++ b/plugins/catalog/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog", "description": "The Backstage plugin for browsing the Backstage catalog", - "version": "1.6.1", + "version": "1.6.2-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/cicd-statistics-module-gitlab/CHANGELOG.md b/plugins/cicd-statistics-module-gitlab/CHANGELOG.md index f510d1a5e0..bbee75ecdd 100644 --- a/plugins/cicd-statistics-module-gitlab/CHANGELOG.md +++ b/plugins/cicd-statistics-module-gitlab/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-cicd-statistics-module-gitlab +## 0.1.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/plugin-cicd-statistics@0.1.14-next.0 + ## 0.1.7 ### Patch Changes diff --git a/plugins/cicd-statistics-module-gitlab/package.json b/plugins/cicd-statistics-module-gitlab/package.json index fab5380e3e..e92d11a977 100644 --- a/plugins/cicd-statistics-module-gitlab/package.json +++ b/plugins/cicd-statistics-module-gitlab/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-cicd-statistics-module-gitlab", "description": "CI/CD Statistics plugin module; Gitlab CICD", - "version": "0.1.7", + "version": "0.1.8-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/cicd-statistics/CHANGELOG.md b/plugins/cicd-statistics/CHANGELOG.md index f0df35a027..ab5ccbe085 100644 --- a/plugins/cicd-statistics/CHANGELOG.md +++ b/plugins/cicd-statistics/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-cicd-statistics +## 0.1.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + ## 0.1.13 ### Patch Changes diff --git a/plugins/cicd-statistics/package.json b/plugins/cicd-statistics/package.json index 372523e3e0..3f7c5e7f60 100644 --- a/plugins/cicd-statistics/package.json +++ b/plugins/cicd-statistics/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-cicd-statistics", "description": "A frontend plugin visualizing CI/CD pipeline statistics (build time)", - "version": "0.1.13", + "version": "0.1.14-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/circleci/CHANGELOG.md b/plugins/circleci/CHANGELOG.md index 5f15c999ea..4fe29f3809 100644 --- a/plugins/circleci/CHANGELOG.md +++ b/plugins/circleci/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-circleci +## 0.3.12-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + ## 0.3.11 ### Patch Changes diff --git a/plugins/circleci/package.json b/plugins/circleci/package.json index 140a5bc7c0..cd895cf6f5 100644 --- a/plugins/circleci/package.json +++ b/plugins/circleci/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-circleci", "description": "A Backstage plugin that integrates towards Circle CI", - "version": "0.3.11", + "version": "0.3.12-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/cloudbuild/CHANGELOG.md b/plugins/cloudbuild/CHANGELOG.md index e4d781ad9e..4cb2c10a48 100644 --- a/plugins/cloudbuild/CHANGELOG.md +++ b/plugins/cloudbuild/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-cloudbuild +## 0.3.12-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + ## 0.3.11 ### Patch Changes diff --git a/plugins/cloudbuild/package.json b/plugins/cloudbuild/package.json index 99a807b74e..1dda3e2844 100644 --- a/plugins/cloudbuild/package.json +++ b/plugins/cloudbuild/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-cloudbuild", "description": "A Backstage plugin that integrates towards Google Cloud Build", - "version": "0.3.11", + "version": "0.3.12-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/code-climate/CHANGELOG.md b/plugins/code-climate/CHANGELOG.md index 38475bbe01..bbf6efe7fa 100644 --- a/plugins/code-climate/CHANGELOG.md +++ b/plugins/code-climate/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-code-climate +## 0.1.12-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + ## 0.1.11 ### Patch Changes diff --git a/plugins/code-climate/package.json b/plugins/code-climate/package.json index 58e5217698..777233f328 100644 --- a/plugins/code-climate/package.json +++ b/plugins/code-climate/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-code-climate", - "version": "0.1.11", + "version": "0.1.12-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/code-coverage-backend/CHANGELOG.md b/plugins/code-coverage-backend/CHANGELOG.md index f8d3263602..4cce8cea7f 100644 --- a/plugins/code-coverage-backend/CHANGELOG.md +++ b/plugins/code-coverage-backend/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-code-coverage-backend +## 0.2.5-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + ## 0.2.4 ### Patch Changes diff --git a/plugins/code-coverage-backend/package.json b/plugins/code-coverage-backend/package.json index f46a6cfa5a..e66d721d93 100644 --- a/plugins/code-coverage-backend/package.json +++ b/plugins/code-coverage-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-code-coverage-backend", "description": "A Backstage backend plugin that helps you keep track of your code coverage", - "version": "0.2.4", + "version": "0.2.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/code-coverage/CHANGELOG.md b/plugins/code-coverage/CHANGELOG.md index 883657fa3a..22fb44be06 100644 --- a/plugins/code-coverage/CHANGELOG.md +++ b/plugins/code-coverage/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-code-coverage +## 0.2.5-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + ## 0.2.4 ### Patch Changes diff --git a/plugins/code-coverage/package.json b/plugins/code-coverage/package.json index 7638faf27e..cab166a1e4 100644 --- a/plugins/code-coverage/package.json +++ b/plugins/code-coverage/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-code-coverage", "description": "A Backstage plugin that helps you keep track of your code coverage", - "version": "0.2.4", + "version": "0.2.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/codescene/CHANGELOG.md b/plugins/codescene/CHANGELOG.md index 1c2257a73f..e1c6ae2238 100644 --- a/plugins/codescene/CHANGELOG.md +++ b/plugins/codescene/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-codescene +## 0.1.7-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- 17a8e32f39: Updated dependency `rc-progress` to `3.4.1`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + ## 0.1.6 ### Patch Changes diff --git a/plugins/codescene/package.json b/plugins/codescene/package.json index 1e98f1ee63..f932ffe3c2 100644 --- a/plugins/codescene/package.json +++ b/plugins/codescene/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-codescene", - "version": "0.1.6", + "version": "0.1.7-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/config-schema/CHANGELOG.md b/plugins/config-schema/CHANGELOG.md index 54b71795d3..07d30d6538 100644 --- a/plugins/config-schema/CHANGELOG.md +++ b/plugins/config-schema/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-config-schema +## 0.1.35-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- 19356df560: Updated dependency `zen-observable` to `^0.9.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + ## 0.1.34 ### Patch Changes diff --git a/plugins/config-schema/package.json b/plugins/config-schema/package.json index 83f693cafe..991526ce05 100644 --- a/plugins/config-schema/package.json +++ b/plugins/config-schema/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-config-schema", "description": "A Backstage plugin that lets you browse the configuration schema of your app", - "version": "0.1.34", + "version": "0.1.35-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/cost-insights/CHANGELOG.md b/plugins/cost-insights/CHANGELOG.md index b57115bf77..6127217642 100644 --- a/plugins/cost-insights/CHANGELOG.md +++ b/plugins/cost-insights/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-cost-insights +## 0.12.1-next.0 + +### Patch Changes + +- f9bbb3be37: Provide the ability to change the base currency from USD to any other currency in cost insights plugin +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-cost-insights-common@0.1.1 + ## 0.12.0 ### Minor Changes diff --git a/plugins/cost-insights/package.json b/plugins/cost-insights/package.json index 9673f72e59..db6227e17b 100644 --- a/plugins/cost-insights/package.json +++ b/plugins/cost-insights/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-cost-insights", "description": "A Backstage plugin that helps you keep track of your cloud spend", - "version": "0.12.0", + "version": "0.12.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/dynatrace/CHANGELOG.md b/plugins/dynatrace/CHANGELOG.md index 4d4b9a232b..7b77434dd0 100644 --- a/plugins/dynatrace/CHANGELOG.md +++ b/plugins/dynatrace/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-dynatrace +## 1.0.2-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + ## 1.0.1 ### Patch Changes diff --git a/plugins/dynatrace/package.json b/plugins/dynatrace/package.json index da99b2767f..398cb270f8 100644 --- a/plugins/dynatrace/package.json +++ b/plugins/dynatrace/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-dynatrace", - "version": "1.0.1", + "version": "1.0.2-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-backend-module-aws-sqs/CHANGELOG.md b/plugins/events-backend-module-aws-sqs/CHANGELOG.md index 8dfa896528..f7014b4009 100644 --- a/plugins/events-backend-module-aws-sqs/CHANGELOG.md +++ b/plugins/events-backend-module-aws-sqs/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-events-backend-module-aws-sqs +## 0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.2.0-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/config@1.0.5-next.0 + ## 0.1.0 ### Minor Changes diff --git a/plugins/events-backend-module-aws-sqs/package.json b/plugins/events-backend-module-aws-sqs/package.json index 096e77b66c..4de90105f4 100644 --- a/plugins/events-backend-module-aws-sqs/package.json +++ b/plugins/events-backend-module-aws-sqs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-aws-sqs", - "version": "0.1.0", + "version": "0.1.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-backend-module-azure/CHANGELOG.md b/plugins/events-backend-module-azure/CHANGELOG.md index 14a06976b0..b17918b6ee 100644 --- a/plugins/events-backend-module-azure/CHANGELOG.md +++ b/plugins/events-backend-module-azure/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-events-backend-module-azure +## 0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.2.0-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + ## 0.1.0 ### Minor Changes diff --git a/plugins/events-backend-module-azure/package.json b/plugins/events-backend-module-azure/package.json index fee8e9117c..4202ecda47 100644 --- a/plugins/events-backend-module-azure/package.json +++ b/plugins/events-backend-module-azure/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-azure", - "version": "0.1.0", + "version": "0.1.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md b/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md index 11a2ade858..fd687b453d 100644 --- a/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md +++ b/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-events-backend-module-bitbucket-cloud +## 0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.2.0-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + ## 0.1.0 ### Minor Changes diff --git a/plugins/events-backend-module-bitbucket-cloud/package.json b/plugins/events-backend-module-bitbucket-cloud/package.json index 8b431a2453..84849f2278 100644 --- a/plugins/events-backend-module-bitbucket-cloud/package.json +++ b/plugins/events-backend-module-bitbucket-cloud/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-bitbucket-cloud", - "version": "0.1.0", + "version": "0.1.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-backend-module-gerrit/CHANGELOG.md b/plugins/events-backend-module-gerrit/CHANGELOG.md index a97bab9ea4..636d7370a6 100644 --- a/plugins/events-backend-module-gerrit/CHANGELOG.md +++ b/plugins/events-backend-module-gerrit/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-events-backend-module-gerrit +## 0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.2.0-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + ## 0.1.0 ### Minor Changes diff --git a/plugins/events-backend-module-gerrit/package.json b/plugins/events-backend-module-gerrit/package.json index 7ec4eda0ec..5048ef2a19 100644 --- a/plugins/events-backend-module-gerrit/package.json +++ b/plugins/events-backend-module-gerrit/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-gerrit", - "version": "0.1.0", + "version": "0.1.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-backend-module-github/CHANGELOG.md b/plugins/events-backend-module-github/CHANGELOG.md index 2de9725228..7bfc68de6e 100644 --- a/plugins/events-backend-module-github/CHANGELOG.md +++ b/plugins/events-backend-module-github/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-events-backend-module-github +## 0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.2.0-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + ## 0.1.0 ### Minor Changes diff --git a/plugins/events-backend-module-github/package.json b/plugins/events-backend-module-github/package.json index 3449a9d9e9..8816adcf79 100644 --- a/plugins/events-backend-module-github/package.json +++ b/plugins/events-backend-module-github/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-github", - "version": "0.1.0", + "version": "0.1.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-backend-module-gitlab/CHANGELOG.md b/plugins/events-backend-module-gitlab/CHANGELOG.md index 9f8f4798f6..55f40a24eb 100644 --- a/plugins/events-backend-module-gitlab/CHANGELOG.md +++ b/plugins/events-backend-module-gitlab/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-events-backend-module-gitlab +## 0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.2.0-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + ## 0.1.0 ### Minor Changes diff --git a/plugins/events-backend-module-gitlab/package.json b/plugins/events-backend-module-gitlab/package.json index c13f9b5289..a376800ca5 100644 --- a/plugins/events-backend-module-gitlab/package.json +++ b/plugins/events-backend-module-gitlab/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-gitlab", - "version": "0.1.0", + "version": "0.1.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-backend-test-utils/CHANGELOG.md b/plugins/events-backend-test-utils/CHANGELOG.md index dd881c011c..0ceab063dc 100644 --- a/plugins/events-backend-test-utils/CHANGELOG.md +++ b/plugins/events-backend-test-utils/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-events-backend-test-utils +## 0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.2.0-next.0 + ## 0.1.0 ### Minor Changes diff --git a/plugins/events-backend-test-utils/package.json b/plugins/events-backend-test-utils/package.json index 3265426ffd..2f573795ba 100644 --- a/plugins/events-backend-test-utils/package.json +++ b/plugins/events-backend-test-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-events-backend-test-utils", "description": "The plugin-events-backend-test-utils for @backstage/plugin-events-node", - "version": "0.1.0", + "version": "0.1.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-backend/CHANGELOG.md b/plugins/events-backend/CHANGELOG.md index a86bf34d03..aef1c3a814 100644 --- a/plugins/events-backend/CHANGELOG.md +++ b/plugins/events-backend/CHANGELOG.md @@ -1,5 +1,40 @@ # @backstage/plugin-events-backend +## 0.2.0-next.0 + +### Minor Changes + +- cf41eedf43: **BREAKING:** Remove required field `router` at `HttpPostIngressEventPublisher.fromConfig` + and replace it with `bind(router: Router)`. + Additionally, the path prefix `/http` will be added inside `HttpPostIngressEventPublisher`. + + ```diff + // at packages/backend/src/plugins/events.ts + const eventsRouter = Router(); + - const httpRouter = Router(); + - eventsRouter.use('/http', httpRouter); + + const http = HttpPostIngressEventPublisher.fromConfig({ + config: env.config, + logger: env.logger, + - router: httpRouter, + }); + + http.bind(eventsRouter); + ``` + +### Patch Changes + +- cf41eedf43: Introduce a new interface `RequestDetails` to abstract `Request` + providing access to request body and headers. + + **BREAKING:** Replace `request: Request` with `request: RequestDetails` at `RequestValidator`. + +- Updated dependencies + - @backstage/plugin-events-node@0.2.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + - @backstage/config@1.0.5-next.0 + ## 0.1.0 ### Minor Changes diff --git a/plugins/events-backend/package.json b/plugins/events-backend/package.json index 48f02667d9..ec07e3a287 100644 --- a/plugins/events-backend/package.json +++ b/plugins/events-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend", - "version": "0.1.0", + "version": "0.2.0-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-node/CHANGELOG.md b/plugins/events-node/CHANGELOG.md index 25899c739e..0a67f77dfd 100644 --- a/plugins/events-node/CHANGELOG.md +++ b/plugins/events-node/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-events-node +## 0.2.0-next.0 + +### Minor Changes + +- cf41eedf43: Introduce a new interface `RequestDetails` to abstract `Request` + providing access to request body and headers. + + **BREAKING:** Replace `request: Request` with `request: RequestDetails` at `RequestValidator`. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.1.5-next.0 + ## 0.1.0 ### Minor Changes diff --git a/plugins/events-node/package.json b/plugins/events-node/package.json index 978037f8ff..0c6fbeef05 100644 --- a/plugins/events-node/package.json +++ b/plugins/events-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-events-node", "description": "The plugin-events-node module for @backstage/plugin-events-backend", - "version": "0.1.0", + "version": "0.2.0-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/example-todo-list-backend/CHANGELOG.md b/plugins/example-todo-list-backend/CHANGELOG.md index a255135f9b..d279bd2f3a 100644 --- a/plugins/example-todo-list-backend/CHANGELOG.md +++ b/plugins/example-todo-list-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @internal/plugin-todo-list-backend +## 1.0.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/plugin-auth-node@0.2.8-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + ## 1.0.7 ### Patch Changes diff --git a/plugins/example-todo-list-backend/package.json b/plugins/example-todo-list-backend/package.json index 02af7e631b..23cce5adbf 100644 --- a/plugins/example-todo-list-backend/package.json +++ b/plugins/example-todo-list-backend/package.json @@ -1,6 +1,6 @@ { "name": "@internal/plugin-todo-list-backend", - "version": "1.0.7", + "version": "1.0.8-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/example-todo-list-common/CHANGELOG.md b/plugins/example-todo-list-common/CHANGELOG.md index b90ea73e78..15c3b64667 100644 --- a/plugins/example-todo-list-common/CHANGELOG.md +++ b/plugins/example-todo-list-common/CHANGELOG.md @@ -1,5 +1,12 @@ # @internal/plugin-todo-list-common +## 1.0.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.2-next.0 + ## 1.0.6 ### Patch Changes diff --git a/plugins/example-todo-list-common/package.json b/plugins/example-todo-list-common/package.json index b38312cd5b..6f8eca4c75 100644 --- a/plugins/example-todo-list-common/package.json +++ b/plugins/example-todo-list-common/package.json @@ -1,6 +1,6 @@ { "name": "@internal/plugin-todo-list-common", - "version": "1.0.6", + "version": "1.0.7-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/example-todo-list/CHANGELOG.md b/plugins/example-todo-list/CHANGELOG.md index 685e92acdb..0023dbfe8b 100644 --- a/plugins/example-todo-list/CHANGELOG.md +++ b/plugins/example-todo-list/CHANGELOG.md @@ -1,5 +1,14 @@ # @internal/plugin-todo-list +## 1.0.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/theme@0.2.16 + ## 1.0.7 ### Patch Changes diff --git a/plugins/example-todo-list/package.json b/plugins/example-todo-list/package.json index 9c7d1de465..95ef8d5238 100644 --- a/plugins/example-todo-list/package.json +++ b/plugins/example-todo-list/package.json @@ -1,6 +1,6 @@ { "name": "@internal/plugin-todo-list", - "version": "1.0.7", + "version": "1.0.8-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/explore-react/CHANGELOG.md b/plugins/explore-react/CHANGELOG.md index 22850a9523..556b919b4f 100644 --- a/plugins/explore-react/CHANGELOG.md +++ b/plugins/explore-react/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-explore-react +## 0.0.24-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.1.1-next.0 + ## 0.0.23 ### Patch Changes diff --git a/plugins/explore-react/package.json b/plugins/explore-react/package.json index 2d65edf074..879a00daa9 100644 --- a/plugins/explore-react/package.json +++ b/plugins/explore-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-explore-react", "description": "A frontend library for Backstage plugins that want to interact with the explore plugin", - "version": "0.0.23", + "version": "0.0.24-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/explore/CHANGELOG.md b/plugins/explore/CHANGELOG.md index af08b68965..6ed2646da9 100644 --- a/plugins/explore/CHANGELOG.md +++ b/plugins/explore/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-explore +## 0.3.43-next.0 + +### Patch Changes + +- ea4a5be8f3: Adds styling to graph forcing it to always fill out the available space. +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-explore-react@0.0.24-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + ## 0.3.42 ### Patch Changes diff --git a/plugins/explore/package.json b/plugins/explore/package.json index 894fd1bc85..f8388df6e8 100644 --- a/plugins/explore/package.json +++ b/plugins/explore/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-explore", "description": "A Backstage plugin for building an exploration page of your software ecosystem", - "version": "0.3.42", + "version": "0.3.43-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/firehydrant/CHANGELOG.md b/plugins/firehydrant/CHANGELOG.md index 28eff9ba0a..f45d554a29 100644 --- a/plugins/firehydrant/CHANGELOG.md +++ b/plugins/firehydrant/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-firehydrant +## 0.1.29-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/theme@0.2.16 + ## 0.1.28 ### Patch Changes diff --git a/plugins/firehydrant/package.json b/plugins/firehydrant/package.json index 20da2966e9..09752fabb4 100644 --- a/plugins/firehydrant/package.json +++ b/plugins/firehydrant/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-firehydrant", "description": "A Backstage plugin that integrates towards FireHydrant", - "version": "0.1.28", + "version": "0.1.29-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/fossa/CHANGELOG.md b/plugins/fossa/CHANGELOG.md index 94ca0b60a1..8f4a4f6411 100644 --- a/plugins/fossa/CHANGELOG.md +++ b/plugins/fossa/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-fossa +## 0.2.44-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + ## 0.2.43 ### Patch Changes diff --git a/plugins/fossa/package.json b/plugins/fossa/package.json index 6127cf17fa..bd5b352f38 100644 --- a/plugins/fossa/package.json +++ b/plugins/fossa/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-fossa", "description": "A Backstage plugin that integrates towards FOSSA", - "version": "0.2.43", + "version": "0.2.44-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/gcalendar/CHANGELOG.md b/plugins/gcalendar/CHANGELOG.md index 316a35f4c8..1247c9af5a 100644 --- a/plugins/gcalendar/CHANGELOG.md +++ b/plugins/gcalendar/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-gcalendar +## 0.3.8-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + ## 0.3.7 ### Patch Changes diff --git a/plugins/gcalendar/package.json b/plugins/gcalendar/package.json index 26a699fa1c..9664f0d1d5 100644 --- a/plugins/gcalendar/package.json +++ b/plugins/gcalendar/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-gcalendar", - "version": "0.3.7", + "version": "0.3.8-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/gcp-projects/CHANGELOG.md b/plugins/gcp-projects/CHANGELOG.md index e07597f6c1..8aebfc2a83 100644 --- a/plugins/gcp-projects/CHANGELOG.md +++ b/plugins/gcp-projects/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-gcp-projects +## 0.3.31-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/theme@0.2.16 + ## 0.3.30 ### Patch Changes diff --git a/plugins/gcp-projects/package.json b/plugins/gcp-projects/package.json index 1592c8bf22..eb0cebacfe 100644 --- a/plugins/gcp-projects/package.json +++ b/plugins/gcp-projects/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-gcp-projects", "description": "A Backstage plugin that helps you manage projects in GCP", - "version": "0.3.30", + "version": "0.3.31-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/git-release-manager/CHANGELOG.md b/plugins/git-release-manager/CHANGELOG.md index b167b3f05d..9e93735c02 100644 --- a/plugins/git-release-manager/CHANGELOG.md +++ b/plugins/git-release-manager/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-git-release-manager +## 0.3.25-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/theme@0.2.16 + ## 0.3.24 ### Patch Changes diff --git a/plugins/git-release-manager/package.json b/plugins/git-release-manager/package.json index c969e89799..3bc48171a0 100644 --- a/plugins/git-release-manager/package.json +++ b/plugins/git-release-manager/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-git-release-manager", "description": "A Backstage plugin that helps you manage releases in git", - "version": "0.3.24", + "version": "0.3.25-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/github-actions/CHANGELOG.md b/plugins/github-actions/CHANGELOG.md index 1c2247c478..e9f0c87449 100644 --- a/plugins/github-actions/CHANGELOG.md +++ b/plugins/github-actions/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-github-actions +## 0.5.12-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + ## 0.5.11 ### Patch Changes diff --git a/plugins/github-actions/package.json b/plugins/github-actions/package.json index ba50324e67..96b45fe403 100644 --- a/plugins/github-actions/package.json +++ b/plugins/github-actions/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-github-actions", "description": "A Backstage plugin that integrates towards GitHub Actions", - "version": "0.5.11", + "version": "0.5.12-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/github-deployments/CHANGELOG.md b/plugins/github-deployments/CHANGELOG.md index ade197c0bc..0cd7ababe1 100644 --- a/plugins/github-deployments/CHANGELOG.md +++ b/plugins/github-deployments/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-github-deployments +## 0.1.43-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration-react@1.1.7-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + ## 0.1.42 ### Patch Changes diff --git a/plugins/github-deployments/package.json b/plugins/github-deployments/package.json index a237c0f45a..984386a609 100644 --- a/plugins/github-deployments/package.json +++ b/plugins/github-deployments/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-github-deployments", "description": "A Backstage plugin that integrates towards GitHub Deployments", - "version": "0.1.42", + "version": "0.1.43-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/github-issues/CHANGELOG.md b/plugins/github-issues/CHANGELOG.md index 799eef210d..dd38eb4ab7 100644 --- a/plugins/github-issues/CHANGELOG.md +++ b/plugins/github-issues/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-github-issues +## 0.2.1-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + ## 0.2.0 ### Minor Changes diff --git a/plugins/github-issues/package.json b/plugins/github-issues/package.json index 11d58c1c35..26d7e58c9e 100644 --- a/plugins/github-issues/package.json +++ b/plugins/github-issues/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-github-issues", - "version": "0.2.0", + "version": "0.2.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/github-pull-requests-board/CHANGELOG.md b/plugins/github-pull-requests-board/CHANGELOG.md index 38e87c02b2..aa286afbb3 100644 --- a/plugins/github-pull-requests-board/CHANGELOG.md +++ b/plugins/github-pull-requests-board/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-github-pull-requests-board +## 0.1.6-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + ## 0.1.5 ### Patch Changes diff --git a/plugins/github-pull-requests-board/package.json b/plugins/github-pull-requests-board/package.json index 24269a7125..c211e9aff5 100644 --- a/plugins/github-pull-requests-board/package.json +++ b/plugins/github-pull-requests-board/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-github-pull-requests-board", "description": "A Backstage plugin that allows you to see all open Pull Requests for all the repositories owned by your team", - "version": "0.1.5", + "version": "0.1.6-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/gitops-profiles/CHANGELOG.md b/plugins/gitops-profiles/CHANGELOG.md index a37503ce7a..35e7a4994d 100644 --- a/plugins/gitops-profiles/CHANGELOG.md +++ b/plugins/gitops-profiles/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-gitops-profiles +## 0.3.30-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/theme@0.2.16 + ## 0.3.29 ### Patch Changes diff --git a/plugins/gitops-profiles/package.json b/plugins/gitops-profiles/package.json index 1644617722..c3db350ccf 100644 --- a/plugins/gitops-profiles/package.json +++ b/plugins/gitops-profiles/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-gitops-profiles", "description": "A Backstage plugin that helps you manage GitOps profiles", - "version": "0.3.29", + "version": "0.3.30-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/gocd/CHANGELOG.md b/plugins/gocd/CHANGELOG.md index 24a1582195..9dfa518ae9 100644 --- a/plugins/gocd/CHANGELOG.md +++ b/plugins/gocd/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-gocd +## 0.1.18-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + ## 0.1.17 ### Patch Changes diff --git a/plugins/gocd/package.json b/plugins/gocd/package.json index 441876b8cf..7c2982a079 100644 --- a/plugins/gocd/package.json +++ b/plugins/gocd/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-gocd", "description": "A Backstage plugin that integrates towards GoCD", - "version": "0.1.17", + "version": "0.1.18-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/graphiql/CHANGELOG.md b/plugins/graphiql/CHANGELOG.md index 66729db2ae..1302e76521 100644 --- a/plugins/graphiql/CHANGELOG.md +++ b/plugins/graphiql/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-graphiql +## 0.2.44-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/theme@0.2.16 + ## 0.2.43 ### Patch Changes diff --git a/plugins/graphiql/package.json b/plugins/graphiql/package.json index bdec4bdba1..9e98cd73e1 100644 --- a/plugins/graphiql/package.json +++ b/plugins/graphiql/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-graphiql", "description": "Backstage plugin for browsing GraphQL APIs", - "version": "0.2.43", + "version": "0.2.44-next.0", "publishConfig": { "access": "public", "main": "dist/index.esm.js", diff --git a/plugins/graphql-backend/CHANGELOG.md b/plugins/graphql-backend/CHANGELOG.md index 783d443df3..e72ff879c0 100644 --- a/plugins/graphql-backend/CHANGELOG.md +++ b/plugins/graphql-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-graphql-backend +## 0.1.29-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/plugin-catalog-graphql@0.3.16-next.0 + - @backstage/config@1.0.5-next.0 + ## 0.1.28 ### Patch Changes diff --git a/plugins/graphql-backend/package.json b/plugins/graphql-backend/package.json index 81e5d0e22a..b591d309dc 100644 --- a/plugins/graphql-backend/package.json +++ b/plugins/graphql-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-graphql-backend", "description": "An experimental Backstage backend plugin for GraphQL", - "version": "0.1.28", + "version": "0.1.29-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/home/CHANGELOG.md b/plugins/home/CHANGELOG.md index 743e79c768..dde9480a9c 100644 --- a/plugins/home/CHANGELOG.md +++ b/plugins/home/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-home +## 0.4.28-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-stack-overflow@0.1.8-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/theme@0.2.16 + ## 0.4.27 ### Patch Changes diff --git a/plugins/home/package.json b/plugins/home/package.json index 0fed1b2022..ac5d35dea1 100644 --- a/plugins/home/package.json +++ b/plugins/home/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-home", "description": "A Backstage plugin that helps you build a home page", - "version": "0.4.27", + "version": "0.4.28-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/ilert/CHANGELOG.md b/plugins/ilert/CHANGELOG.md index 013ddf42ae..eb2cf7b9bd 100644 --- a/plugins/ilert/CHANGELOG.md +++ b/plugins/ilert/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-ilert +## 0.2.1-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + ## 0.2.0 ### Minor Changes diff --git a/plugins/ilert/package.json b/plugins/ilert/package.json index e01ff50617..6fec626262 100644 --- a/plugins/ilert/package.json +++ b/plugins/ilert/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-ilert", "description": "A Backstage plugin that integrates towards iLert", - "version": "0.2.0", + "version": "0.2.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/jenkins-backend/CHANGELOG.md b/plugins/jenkins-backend/CHANGELOG.md index 5b7ec769d1..a770057e25 100644 --- a/plugins/jenkins-backend/CHANGELOG.md +++ b/plugins/jenkins-backend/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-jenkins-backend +## 0.1.29-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/plugin-auth-node@0.2.8-next.0 + - @backstage/plugin-permission-common@0.7.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/plugin-jenkins-common@0.1.11-next.0 + ## 0.1.28 ### Patch Changes diff --git a/plugins/jenkins-backend/package.json b/plugins/jenkins-backend/package.json index 60b96cb694..2bf84d3bc1 100644 --- a/plugins/jenkins-backend/package.json +++ b/plugins/jenkins-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-jenkins-backend", "description": "A Backstage backend plugin that integrates towards Jenkins", - "version": "0.1.28", + "version": "0.1.29-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/jenkins-common/CHANGELOG.md b/plugins/jenkins-common/CHANGELOG.md index 3fb300fecc..9027bb6529 100644 --- a/plugins/jenkins-common/CHANGELOG.md +++ b/plugins/jenkins-common/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-jenkins-common +## 0.1.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.2-next.0 + - @backstage/plugin-catalog-common@1.0.9-next.0 + ## 0.1.10 ### Patch Changes diff --git a/plugins/jenkins-common/package.json b/plugins/jenkins-common/package.json index 90c7e269eb..4f44a626ce 100644 --- a/plugins/jenkins-common/package.json +++ b/plugins/jenkins-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-jenkins-common", - "version": "0.1.10", + "version": "0.1.11-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/jenkins/CHANGELOG.md b/plugins/jenkins/CHANGELOG.md index c9a6f7dcc3..576508da14 100644 --- a/plugins/jenkins/CHANGELOG.md +++ b/plugins/jenkins/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-jenkins +## 0.7.11-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-jenkins-common@0.1.11-next.0 + ## 0.7.10 ### Patch Changes diff --git a/plugins/jenkins/package.json b/plugins/jenkins/package.json index 157f91944e..a1d90e3de0 100644 --- a/plugins/jenkins/package.json +++ b/plugins/jenkins/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-jenkins", "description": "A Backstage plugin that integrates towards Jenkins", - "version": "0.7.10", + "version": "0.7.11-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/kafka-backend/CHANGELOG.md b/plugins/kafka-backend/CHANGELOG.md index 4da0ca13e4..583858e130 100644 --- a/plugins/kafka-backend/CHANGELOG.md +++ b/plugins/kafka-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-kafka-backend +## 0.2.32-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + ## 0.2.31 ### Patch Changes diff --git a/plugins/kafka-backend/package.json b/plugins/kafka-backend/package.json index 1f5ac500f8..a3bdf9d53a 100644 --- a/plugins/kafka-backend/package.json +++ b/plugins/kafka-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kafka-backend", "description": "A Backstage backend plugin that integrates towards Kafka", - "version": "0.2.31", + "version": "0.2.32-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/kafka/CHANGELOG.md b/plugins/kafka/CHANGELOG.md index 1e9589d034..59664b40fb 100644 --- a/plugins/kafka/CHANGELOG.md +++ b/plugins/kafka/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-kafka +## 0.3.12-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/theme@0.2.16 + ## 0.3.11 ### Patch Changes diff --git a/plugins/kafka/package.json b/plugins/kafka/package.json index 851d2d7ef3..0aae08d6dc 100644 --- a/plugins/kafka/package.json +++ b/plugins/kafka/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kafka", "description": "A Backstage plugin that integrates towards Kafka", - "version": "0.3.11", + "version": "0.3.12-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/kubernetes-backend/CHANGELOG.md b/plugins/kubernetes-backend/CHANGELOG.md index e1f0a2df4e..d88425cde2 100644 --- a/plugins/kubernetes-backend/CHANGELOG.md +++ b/plugins/kubernetes-backend/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-kubernetes-backend +## 0.8.1-next.0 + +### Patch Changes + +- b585179770: Added Kubernetes proxy API route to backend Kubernetes plugin, allowing Backstage plugin developers to read/write new information from Kubernetes (if proper credentials are provided). +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/backend-test-utils@0.1.31-next.0 + - @backstage/plugin-auth-node@0.2.8-next.0 + - @backstage/plugin-kubernetes-common@0.4.5-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + ## 0.8.0 ### Minor Changes diff --git a/plugins/kubernetes-backend/package.json b/plugins/kubernetes-backend/package.json index c0822d366a..4e17a04bd0 100644 --- a/plugins/kubernetes-backend/package.json +++ b/plugins/kubernetes-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kubernetes-backend", "description": "A Backstage backend plugin that integrates towards Kubernetes", - "version": "0.8.0", + "version": "0.8.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/kubernetes-common/CHANGELOG.md b/plugins/kubernetes-common/CHANGELOG.md index 3a255e7525..c7e7e2851e 100644 --- a/plugins/kubernetes-common/CHANGELOG.md +++ b/plugins/kubernetes-common/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-kubernetes-common +## 0.4.5-next.0 + +### Patch Changes + +- b585179770: Added Kubernetes proxy API route to backend Kubernetes plugin, allowing Backstage plugin developers to read/write new information from Kubernetes (if proper credentials are provided). +- Updated dependencies + - @backstage/catalog-model@1.1.4-next.0 + ## 0.4.4 ### Patch Changes diff --git a/plugins/kubernetes-common/package.json b/plugins/kubernetes-common/package.json index f82c8bb9d9..0bc877106d 100644 --- a/plugins/kubernetes-common/package.json +++ b/plugins/kubernetes-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kubernetes-common", "description": "Common functionalities for kubernetes, to be shared between kubernetes and kubernetes-backend plugin", - "version": "0.4.4", + "version": "0.4.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/kubernetes/CHANGELOG.md b/plugins/kubernetes/CHANGELOG.md index f01d0b8db4..fcf6872b45 100644 --- a/plugins/kubernetes/CHANGELOG.md +++ b/plugins/kubernetes/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-kubernetes +## 0.7.5-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/plugin-kubernetes-common@0.4.5-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/theme@0.2.16 + ## 0.7.4 ### Patch Changes diff --git a/plugins/kubernetes/package.json b/plugins/kubernetes/package.json index c00bbd5083..f85c8f55d4 100644 --- a/plugins/kubernetes/package.json +++ b/plugins/kubernetes/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kubernetes", "description": "A Backstage plugin that integrates towards Kubernetes", - "version": "0.7.4", + "version": "0.7.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/lighthouse/CHANGELOG.md b/plugins/lighthouse/CHANGELOG.md index f47334f73c..94a1de76a5 100644 --- a/plugins/lighthouse/CHANGELOG.md +++ b/plugins/lighthouse/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-lighthouse +## 0.3.12-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/theme@0.2.16 + ## 0.3.11 ### Patch Changes diff --git a/plugins/lighthouse/package.json b/plugins/lighthouse/package.json index b27fc62655..81eb8ae4ad 100644 --- a/plugins/lighthouse/package.json +++ b/plugins/lighthouse/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-lighthouse", "description": "A Backstage plugin that integrates towards Lighthouse", - "version": "0.3.11", + "version": "0.3.12-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/newrelic-dashboard/CHANGELOG.md b/plugins/newrelic-dashboard/CHANGELOG.md index 39a1e77549..0f77c55636 100644 --- a/plugins/newrelic-dashboard/CHANGELOG.md +++ b/plugins/newrelic-dashboard/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-newrelic-dashboard +## 0.2.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + ## 0.2.4 ### Patch Changes diff --git a/plugins/newrelic-dashboard/package.json b/plugins/newrelic-dashboard/package.json index 2766346636..e18927d13a 100644 --- a/plugins/newrelic-dashboard/package.json +++ b/plugins/newrelic-dashboard/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-newrelic-dashboard", - "version": "0.2.4", + "version": "0.2.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/newrelic/CHANGELOG.md b/plugins/newrelic/CHANGELOG.md index 328c73e448..22f3296a99 100644 --- a/plugins/newrelic/CHANGELOG.md +++ b/plugins/newrelic/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-newrelic +## 0.3.30-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/theme@0.2.16 + ## 0.3.29 ### Patch Changes diff --git a/plugins/newrelic/package.json b/plugins/newrelic/package.json index 01408ccbfb..1b1cdb748d 100644 --- a/plugins/newrelic/package.json +++ b/plugins/newrelic/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-newrelic", "description": "A Backstage plugin that integrates towards New Relic", - "version": "0.3.29", + "version": "0.3.30-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/org-react/CHANGELOG.md b/plugins/org-react/CHANGELOG.md index c84b6306c9..a32be25eb3 100644 --- a/plugins/org-react/CHANGELOG.md +++ b/plugins/org-react/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-org-react +## 0.1.1-next.0 + +### Patch Changes + +- 4cb5066828: Bug fixes and adding the possibility to add a default value for the `GroupListPicker`. Fixes: Vertical size jump on text entry, left align for text, selecting a value closes the popup, auto focus on the popup when opening +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + ## 0.1.0 ### Minor Changes diff --git a/plugins/org-react/package.json b/plugins/org-react/package.json index 522096e26a..ced20576b3 100644 --- a/plugins/org-react/package.json +++ b/plugins/org-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-org-react", - "version": "0.1.0", + "version": "0.1.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/org/CHANGELOG.md b/plugins/org/CHANGELOG.md index 6bfce1e679..ff5bafa2c1 100644 --- a/plugins/org/CHANGELOG.md +++ b/plugins/org/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-org +## 0.6.1-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + ## 0.6.0 ### Minor Changes diff --git a/plugins/org/package.json b/plugins/org/package.json index c628d9f762..8daaf47f65 100644 --- a/plugins/org/package.json +++ b/plugins/org/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-org", "description": "A Backstage plugin that helps you create entity pages for your organization", - "version": "0.6.0", + "version": "0.6.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/pagerduty/CHANGELOG.md b/plugins/pagerduty/CHANGELOG.md index c8f4e7cc4f..7849f8eab9 100644 --- a/plugins/pagerduty/CHANGELOG.md +++ b/plugins/pagerduty/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-pagerduty +## 0.5.5-next.0 + +### Patch Changes + +- cb716004ef: Internal refactor to improve tests +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + ## 0.5.4 ### Patch Changes diff --git a/plugins/pagerduty/package.json b/plugins/pagerduty/package.json index 8dbd63494e..6d11107598 100644 --- a/plugins/pagerduty/package.json +++ b/plugins/pagerduty/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-pagerduty", "description": "A Backstage plugin that integrates towards PagerDuty", - "version": "0.5.4", + "version": "0.5.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/periskop-backend/CHANGELOG.md b/plugins/periskop-backend/CHANGELOG.md index 7725bf2fe0..d031743fbc 100644 --- a/plugins/periskop-backend/CHANGELOG.md +++ b/plugins/periskop-backend/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-periskop-backend +## 0.1.10-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/config@1.0.5-next.0 + ## 0.1.9 ### Patch Changes diff --git a/plugins/periskop-backend/package.json b/plugins/periskop-backend/package.json index 07e181357d..a837bc6d31 100644 --- a/plugins/periskop-backend/package.json +++ b/plugins/periskop-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-periskop-backend", - "version": "0.1.9", + "version": "0.1.10-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/periskop/CHANGELOG.md b/plugins/periskop/CHANGELOG.md index 3c583dd8da..5c5acf7941 100644 --- a/plugins/periskop/CHANGELOG.md +++ b/plugins/periskop/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-periskop +## 0.1.10-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + ## 0.1.9 ### Patch Changes diff --git a/plugins/periskop/package.json b/plugins/periskop/package.json index bf07e96ccb..f0ab1126a1 100644 --- a/plugins/periskop/package.json +++ b/plugins/periskop/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-periskop", - "version": "0.1.9", + "version": "0.1.10-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/permission-backend/CHANGELOG.md b/plugins/permission-backend/CHANGELOG.md index b8d42cf4cf..3fb59d8527 100644 --- a/plugins/permission-backend/CHANGELOG.md +++ b/plugins/permission-backend/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-permission-backend +## 0.5.14-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/plugin-auth-node@0.2.8-next.0 + - @backstage/plugin-permission-common@0.7.2-next.0 + - @backstage/plugin-permission-node@0.7.2-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + ## 0.5.13 ### Patch Changes diff --git a/plugins/permission-backend/package.json b/plugins/permission-backend/package.json index f40f8999e6..7eca3e77c6 100644 --- a/plugins/permission-backend/package.json +++ b/plugins/permission-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-permission-backend", - "version": "0.5.13", + "version": "0.5.14-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/permission-common/CHANGELOG.md b/plugins/permission-common/CHANGELOG.md index b5599964b9..53931c40dc 100644 --- a/plugins/permission-common/CHANGELOG.md +++ b/plugins/permission-common/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-permission-common +## 0.7.2-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/types@1.0.2-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + ## 0.7.1 ### Patch Changes diff --git a/plugins/permission-common/package.json b/plugins/permission-common/package.json index db21171632..fb3caa9150 100644 --- a/plugins/permission-common/package.json +++ b/plugins/permission-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-permission-common", "description": "Isomorphic types and client for Backstage permissions and authorization", - "version": "0.7.1", + "version": "0.7.2-next.0", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/plugins/permission-node/CHANGELOG.md b/plugins/permission-node/CHANGELOG.md index 743c2af016..7380e08131 100644 --- a/plugins/permission-node/CHANGELOG.md +++ b/plugins/permission-node/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-permission-node +## 0.7.2-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/plugin-auth-node@0.2.8-next.0 + - @backstage/plugin-permission-common@0.7.2-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + ## 0.7.1 ### Patch Changes diff --git a/plugins/permission-node/package.json b/plugins/permission-node/package.json index 16fb15b569..5971448783 100644 --- a/plugins/permission-node/package.json +++ b/plugins/permission-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-permission-node", "description": "Common permission and authorization utilities for backend plugins", - "version": "0.7.1", + "version": "0.7.2-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/permission-react/CHANGELOG.md b/plugins/permission-react/CHANGELOG.md index ef4d4f46ff..3219389c85 100644 --- a/plugins/permission-react/CHANGELOG.md +++ b/plugins/permission-react/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-permission-react +## 0.4.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-permission-common@0.7.2-next.0 + - @backstage/config@1.0.5-next.0 + ## 0.4.7 ### Patch Changes diff --git a/plugins/permission-react/package.json b/plugins/permission-react/package.json index 2f978efc38..43537875c2 100644 --- a/plugins/permission-react/package.json +++ b/plugins/permission-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-permission-react", - "version": "0.4.7", + "version": "0.4.8-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/playlist-backend/CHANGELOG.md b/plugins/playlist-backend/CHANGELOG.md index ef38cbc96e..24b14aa6b2 100644 --- a/plugins/playlist-backend/CHANGELOG.md +++ b/plugins/playlist-backend/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-playlist-backend +## 0.2.2-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/backend-test-utils@0.1.31-next.0 + - @backstage/plugin-auth-node@0.2.8-next.0 + - @backstage/plugin-permission-common@0.7.2-next.0 + - @backstage/plugin-permission-node@0.7.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/plugin-playlist-common@0.1.3-next.0 + ## 0.2.1 ### Patch Changes diff --git a/plugins/playlist-backend/package.json b/plugins/playlist-backend/package.json index 3e3c0967e0..ddbca7aeac 100644 --- a/plugins/playlist-backend/package.json +++ b/plugins/playlist-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-playlist-backend", - "version": "0.2.1", + "version": "0.2.2-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/playlist-common/CHANGELOG.md b/plugins/playlist-common/CHANGELOG.md index 89cb9934f9..99e2dacdbb 100644 --- a/plugins/playlist-common/CHANGELOG.md +++ b/plugins/playlist-common/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-playlist-common +## 0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.2-next.0 + ## 0.1.2 ### Patch Changes diff --git a/plugins/playlist-common/package.json b/plugins/playlist-common/package.json index baeb49d1ba..01823b4e24 100644 --- a/plugins/playlist-common/package.json +++ b/plugins/playlist-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-playlist-common", "description": "Common functionalities for the playlist plugin", - "version": "0.1.2", + "version": "0.1.3-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/playlist/CHANGELOG.md b/plugins/playlist/CHANGELOG.md index 9f965ead21..2be4e0375a 100644 --- a/plugins/playlist/CHANGELOG.md +++ b/plugins/playlist/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-playlist +## 0.1.3-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-permission-common@0.7.2-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-common@1.0.9-next.0 + - @backstage/plugin-permission-react@0.4.8-next.0 + - @backstage/plugin-playlist-common@0.1.3-next.0 + - @backstage/plugin-search-react@1.2.2-next.0 + ## 0.1.2 ### Patch Changes diff --git a/plugins/playlist/package.json b/plugins/playlist/package.json index 6b1e40d880..821b337aa6 100644 --- a/plugins/playlist/package.json +++ b/plugins/playlist/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-playlist", - "version": "0.1.2", + "version": "0.1.3-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/proxy-backend/CHANGELOG.md b/plugins/proxy-backend/CHANGELOG.md index 047565b294..771898ed46 100644 --- a/plugins/proxy-backend/CHANGELOG.md +++ b/plugins/proxy-backend/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-proxy-backend +## 0.2.33-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/config@1.0.5-next.0 + ## 0.2.32 ### Patch Changes diff --git a/plugins/proxy-backend/package.json b/plugins/proxy-backend/package.json index acb8a59c6d..5bc9bbc241 100644 --- a/plugins/proxy-backend/package.json +++ b/plugins/proxy-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-proxy-backend", "description": "A Backstage backend plugin that helps you set up proxy endpoints in the backend", - "version": "0.2.32", + "version": "0.2.33-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/rollbar-backend/CHANGELOG.md b/plugins/rollbar-backend/CHANGELOG.md index c4dd8ca52c..cf967df7e8 100644 --- a/plugins/rollbar-backend/CHANGELOG.md +++ b/plugins/rollbar-backend/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-rollbar-backend +## 0.1.36-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/config@1.0.5-next.0 + ## 0.1.35 ### Patch Changes diff --git a/plugins/rollbar-backend/package.json b/plugins/rollbar-backend/package.json index 5b69fde3f6..2af265e40c 100644 --- a/plugins/rollbar-backend/package.json +++ b/plugins/rollbar-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-rollbar-backend", "description": "A Backstage backend plugin that integrates towards Rollbar", - "version": "0.1.35", + "version": "0.1.36-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/rollbar/CHANGELOG.md b/plugins/rollbar/CHANGELOG.md index 47ebcbd1f0..0408c6833f 100644 --- a/plugins/rollbar/CHANGELOG.md +++ b/plugins/rollbar/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-rollbar +## 0.4.12-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + ## 0.4.11 ### Patch Changes diff --git a/plugins/rollbar/package.json b/plugins/rollbar/package.json index 72e2a0aaf0..43865329b4 100644 --- a/plugins/rollbar/package.json +++ b/plugins/rollbar/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-rollbar", "description": "A Backstage plugin that integrates towards Rollbar", - "version": "0.4.11", + "version": "0.4.12-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md b/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md index 4c108955cc..4de8f869b7 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-scaffolder-backend-module-cookiecutter +## 0.2.14-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.8.1-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + ## 0.2.13 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-cookiecutter/package.json b/plugins/scaffolder-backend-module-cookiecutter/package.json index ab36ba6d57..00422d15c7 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/package.json +++ b/plugins/scaffolder-backend-module-cookiecutter/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-backend-module-cookiecutter", "description": "A module for the scaffolder backend that lets you template projects using cookiecutter", - "version": "0.2.13", + "version": "0.2.14-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend-module-rails/CHANGELOG.md b/plugins/scaffolder-backend-module-rails/CHANGELOG.md index cf235ed430..f2c533d287 100644 --- a/plugins/scaffolder-backend-module-rails/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-rails/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-scaffolder-backend-module-rails +## 0.4.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.8.1-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + ## 0.4.6 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-rails/package.json b/plugins/scaffolder-backend-module-rails/package.json index a068484bdc..885cf0ba64 100644 --- a/plugins/scaffolder-backend-module-rails/package.json +++ b/plugins/scaffolder-backend-module-rails/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-backend-module-rails", "description": "A module for the scaffolder backend that lets you template projects using Rails", - "version": "0.4.6", + "version": "0.4.7-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md b/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md index 745f478ecc..0bf5a78f89 100644 --- a/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-scaffolder-backend-module-yeoman +## 0.2.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.8.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/config@1.0.5-next.0 + ## 0.2.11 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-yeoman/package.json b/plugins/scaffolder-backend-module-yeoman/package.json index a1d17283ed..2f8c0ef92a 100644 --- a/plugins/scaffolder-backend-module-yeoman/package.json +++ b/plugins/scaffolder-backend-module-yeoman/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-yeoman", - "version": "0.2.11", + "version": "0.2.12-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend/CHANGELOG.md b/plugins/scaffolder-backend/CHANGELOG.md index bdafef8ee3..e5a30fcace 100644 --- a/plugins/scaffolder-backend/CHANGELOG.md +++ b/plugins/scaffolder-backend/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-scaffolder-backend +## 1.8.1-next.0 + +### Patch Changes + +- cb716004ef: Internal refactor to improve tests +- 26404430bc: Use Json types from @backstage/types +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- 19356df560: Updated dependency `zen-observable` to `^0.9.0`. +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/plugin-catalog-backend@1.6.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/plugin-auth-node@0.2.8-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/backend-plugin-api@0.1.5-next.0 + - @backstage/plugin-catalog-node@1.2.2-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/plugin-scaffolder-common@1.2.3-next.0 + ## 1.8.0 ### Minor Changes diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index 60542e9ead..ae139a6fcf 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-backend", "description": "The Backstage backend plugin that helps you create new things", - "version": "1.8.0", + "version": "1.8.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-common/CHANGELOG.md b/plugins/scaffolder-common/CHANGELOG.md index 88cdd66d95..e0089191db 100644 --- a/plugins/scaffolder-common/CHANGELOG.md +++ b/plugins/scaffolder-common/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-scaffolder-common +## 1.2.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.0.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + ## 1.2.2 ### Patch Changes diff --git a/plugins/scaffolder-common/package.json b/plugins/scaffolder-common/package.json index 4c244d4535..ee86ae545c 100644 --- a/plugins/scaffolder-common/package.json +++ b/plugins/scaffolder-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-common", "description": "Common functionalities for the scaffolder, to be shared between scaffolder and scaffolder-backend plugin", - "version": "1.2.2", + "version": "1.2.3-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder/CHANGELOG.md b/plugins/scaffolder/CHANGELOG.md index d40cacd62b..def68546c9 100644 --- a/plugins/scaffolder/CHANGELOG.md +++ b/plugins/scaffolder/CHANGELOG.md @@ -1,5 +1,42 @@ # @backstage/plugin-scaffolder +## 1.9.0-next.0 + +### Minor Changes + +- ddd1c3308d: Implement Custom Field Explorer to view and play around with available installed custom field extensions +- adb1b01e32: Adds the ability to supply a `transformErrors` function to the `Stepper` for `/next` + +### Patch Changes + +- d4d07cf55e: Enabling the customization of the last step in the scaffolder template. + + To override the content you have to do the next: + + ```typescript jsx + + ``` + +- ef803022f1: Initialize all `formData` in the `Stepper` in `/next` +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- 19356df560: Updated dependency `zen-observable` to `^0.9.0`. +- a63e2df559: fixed `headerOptions` not passed to `TemplatePage` component +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration-react@1.1.7-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-common@1.0.9-next.0 + - @backstage/plugin-permission-react@0.4.8-next.0 + - @backstage/plugin-scaffolder-common@1.2.3-next.0 + ## 1.8.0 ### Minor Changes diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index 1ef758c079..5f99f43939 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder", "description": "The Backstage plugin that helps you create new things", - "version": "1.8.0", + "version": "1.9.0-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-backend-module-elasticsearch/CHANGELOG.md b/plugins/search-backend-module-elasticsearch/CHANGELOG.md index f808ffb752..53b506a0a3 100644 --- a/plugins/search-backend-module-elasticsearch/CHANGELOG.md +++ b/plugins/search-backend-module-elasticsearch/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-search-backend-module-elasticsearch +## 1.0.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-node@1.0.5-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/plugin-search-common@1.1.2-next.0 + ## 1.0.4 ### Patch Changes diff --git a/plugins/search-backend-module-elasticsearch/package.json b/plugins/search-backend-module-elasticsearch/package.json index 945ecfed15..0687ecfb20 100644 --- a/plugins/search-backend-module-elasticsearch/package.json +++ b/plugins/search-backend-module-elasticsearch/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend-module-elasticsearch", "description": "A module for the search backend that implements search using ElasticSearch", - "version": "1.0.4", + "version": "1.0.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-backend-module-pg/CHANGELOG.md b/plugins/search-backend-module-pg/CHANGELOG.md index c84b823149..608a147f26 100644 --- a/plugins/search-backend-module-pg/CHANGELOG.md +++ b/plugins/search-backend-module-pg/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-search-backend-module-pg +## 0.4.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-node@1.0.5-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/plugin-search-common@1.1.2-next.0 + ## 0.4.2 ### Patch Changes diff --git a/plugins/search-backend-module-pg/package.json b/plugins/search-backend-module-pg/package.json index 0dad5637e6..a40e42a4de 100644 --- a/plugins/search-backend-module-pg/package.json +++ b/plugins/search-backend-module-pg/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend-module-pg", "description": "A module for the search backend that implements search using PostgreSQL", - "version": "0.4.2", + "version": "0.4.3-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-backend-node/CHANGELOG.md b/plugins/search-backend-node/CHANGELOG.md index 209fa9e0c4..935b51d335 100644 --- a/plugins/search-backend-node/CHANGELOG.md +++ b/plugins/search-backend-node/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-search-backend-node +## 1.0.5-next.0 + +### Patch Changes + +- a962ce0551: Wait for indexer initialization before finalizing indexing. +- 683ced83f6: Fixed a bug that could cause a `max listeners exceeded warning` to be logged when more than 10 collators were running simultaneously. +- 81b1e7b0fe: Updated indexer and decorator base classes to take advantage of features introduced in Node.js v16; be sure you are running a [supported version of Node.js](https://backstage.io/docs/releases/v1.8.0#node-16-and-18). +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/plugin-permission-common@0.7.2-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/plugin-search-common@1.1.2-next.0 + ## 1.0.4 ### Patch Changes diff --git a/plugins/search-backend-node/package.json b/plugins/search-backend-node/package.json index 2dc9e150a0..8a15127040 100644 --- a/plugins/search-backend-node/package.json +++ b/plugins/search-backend-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend-node", "description": "A library for Backstage backend plugins that want to interact with the search backend plugin", - "version": "1.0.4", + "version": "1.0.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-backend/CHANGELOG.md b/plugins/search-backend/CHANGELOG.md index a260266c64..c468790b9c 100644 --- a/plugins/search-backend/CHANGELOG.md +++ b/plugins/search-backend/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-search-backend +## 1.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-node@1.0.5-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/plugin-auth-node@0.2.8-next.0 + - @backstage/plugin-permission-common@0.7.2-next.0 + - @backstage/plugin-permission-node@0.7.2-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/plugin-search-common@1.1.2-next.0 + ## 1.1.1 ### Patch Changes diff --git a/plugins/search-backend/package.json b/plugins/search-backend/package.json index 834886e6f0..3eee5ff5f0 100644 --- a/plugins/search-backend/package.json +++ b/plugins/search-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend", "description": "The Backstage backend plugin that provides your backstage app with search", - "version": "1.1.1", + "version": "1.1.2-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-common/CHANGELOG.md b/plugins/search-common/CHANGELOG.md index 816230ee1f..c0862e460c 100644 --- a/plugins/search-common/CHANGELOG.md +++ b/plugins/search-common/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-search-common +## 1.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.2-next.0 + - @backstage/types@1.0.2-next.0 + ## 1.1.1 ### Patch Changes diff --git a/plugins/search-common/package.json b/plugins/search-common/package.json index 918213ec54..b35c3ab532 100644 --- a/plugins/search-common/package.json +++ b/plugins/search-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-common", "description": "Common functionalities for Search, to be shared between various search-enabled plugins", - "version": "1.1.1", + "version": "1.1.2-next.0", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/plugins/search-react/CHANGELOG.md b/plugins/search-react/CHANGELOG.md index 8cf413bbb7..52c30a7af1 100644 --- a/plugins/search-react/CHANGELOG.md +++ b/plugins/search-react/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-search-react +## 1.2.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/theme@0.2.16 + - @backstage/version-bridge@1.0.2 + - @backstage/plugin-search-common@1.1.2-next.0 + ## 1.2.1 ### Patch Changes diff --git a/plugins/search-react/package.json b/plugins/search-react/package.json index 71308297e2..4c277daac2 100644 --- a/plugins/search-react/package.json +++ b/plugins/search-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-react", - "version": "1.2.1", + "version": "1.2.2-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search/CHANGELOG.md b/plugins/search/CHANGELOG.md index ca0385d0ba..5abbc5847b 100644 --- a/plugins/search/CHANGELOG.md +++ b/plugins/search/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-search +## 1.0.5-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + - @backstage/version-bridge@1.0.2 + - @backstage/plugin-search-common@1.1.2-next.0 + - @backstage/plugin-search-react@1.2.2-next.0 + ## 1.0.4 ### Patch Changes diff --git a/plugins/search/package.json b/plugins/search/package.json index 33282faaf9..7602e96273 100644 --- a/plugins/search/package.json +++ b/plugins/search/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search", "description": "The Backstage plugin that provides your backstage app with search", - "version": "1.0.4", + "version": "1.0.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/sentry/CHANGELOG.md b/plugins/sentry/CHANGELOG.md index 31eb58a5ea..9bc0d89bf0 100644 --- a/plugins/sentry/CHANGELOG.md +++ b/plugins/sentry/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-sentry +## 0.4.5-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + ## 0.4.4 ### Patch Changes diff --git a/plugins/sentry/package.json b/plugins/sentry/package.json index 7a94be4841..4d83821fef 100644 --- a/plugins/sentry/package.json +++ b/plugins/sentry/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-sentry", "description": "A Backstage plugin that integrates towards Sentry", - "version": "0.4.4", + "version": "0.4.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/shortcuts/CHANGELOG.md b/plugins/shortcuts/CHANGELOG.md index a7a499c87f..9caaea3d44 100644 --- a/plugins/shortcuts/CHANGELOG.md +++ b/plugins/shortcuts/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-shortcuts +## 0.3.4-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- 19356df560: Updated dependency `zen-observable` to `^0.9.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/theme@0.2.16 + ## 0.3.3 ### Patch Changes diff --git a/plugins/shortcuts/package.json b/plugins/shortcuts/package.json index 62581364f7..a32a83989f 100644 --- a/plugins/shortcuts/package.json +++ b/plugins/shortcuts/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-shortcuts", "description": "A Backstage plugin that provides a shortcuts feature to the sidebar", - "version": "0.3.3", + "version": "0.3.4-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/sonarqube-backend/CHANGELOG.md b/plugins/sonarqube-backend/CHANGELOG.md index a76482ae32..e574f9677e 100644 --- a/plugins/sonarqube-backend/CHANGELOG.md +++ b/plugins/sonarqube-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-sonarqube-backend +## 0.1.4-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + ## 0.1.3 ### Patch Changes diff --git a/plugins/sonarqube-backend/package.json b/plugins/sonarqube-backend/package.json index 674eea9663..ba46e2bcc1 100644 --- a/plugins/sonarqube-backend/package.json +++ b/plugins/sonarqube-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-sonarqube-backend", - "version": "0.1.3", + "version": "0.1.4-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/sonarqube/CHANGELOG.md b/plugins/sonarqube/CHANGELOG.md index 4c92de36ea..4fdf03eb53 100644 --- a/plugins/sonarqube/CHANGELOG.md +++ b/plugins/sonarqube/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-sonarqube +## 0.5.1-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- 17a8e32f39: Updated dependency `rc-progress` to `3.4.1`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + ## 0.5.0 ### Minor Changes diff --git a/plugins/sonarqube/package.json b/plugins/sonarqube/package.json index eba873d208..cc3757ac3c 100644 --- a/plugins/sonarqube/package.json +++ b/plugins/sonarqube/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-sonarqube", "description": "", - "version": "0.5.0", + "version": "0.5.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/splunk-on-call/CHANGELOG.md b/plugins/splunk-on-call/CHANGELOG.md index 35bf66f661..0fdd94313d 100644 --- a/plugins/splunk-on-call/CHANGELOG.md +++ b/plugins/splunk-on-call/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-splunk-on-call +## 0.4.1-next.0 + +### Patch Changes + +- cb716004ef: Internal refactor to improve tests +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/theme@0.2.16 + ## 0.4.0 ### Minor Changes diff --git a/plugins/splunk-on-call/package.json b/plugins/splunk-on-call/package.json index c184f2aeab..f1abb63b97 100644 --- a/plugins/splunk-on-call/package.json +++ b/plugins/splunk-on-call/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-splunk-on-call", "description": "A Backstage plugin that integrates towards Splunk On-Call", - "version": "0.4.0", + "version": "0.4.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/stack-overflow-backend/CHANGELOG.md b/plugins/stack-overflow-backend/CHANGELOG.md index 4f4ba31caf..ebeefd5cbd 100644 --- a/plugins/stack-overflow-backend/CHANGELOG.md +++ b/plugins/stack-overflow-backend/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-stack-overflow-backend +## 0.1.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.21.2-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/plugin-search-common@1.1.2-next.0 + ## 0.1.7 ### Patch Changes diff --git a/plugins/stack-overflow-backend/package.json b/plugins/stack-overflow-backend/package.json index a31d1c1d14..80c45c3554 100644 --- a/plugins/stack-overflow-backend/package.json +++ b/plugins/stack-overflow-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-stack-overflow-backend", - "version": "0.1.7", + "version": "0.1.8-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/stack-overflow/CHANGELOG.md b/plugins/stack-overflow/CHANGELOG.md index 3e97f1b293..7bc2866dfe 100644 --- a/plugins/stack-overflow/CHANGELOG.md +++ b/plugins/stack-overflow/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-stack-overflow +## 0.1.8-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-home@0.4.28-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-search-common@1.1.2-next.0 + ## 0.1.7 ### Patch Changes diff --git a/plugins/stack-overflow/package.json b/plugins/stack-overflow/package.json index e6e75d8183..cc0f6f615a 100644 --- a/plugins/stack-overflow/package.json +++ b/plugins/stack-overflow/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-stack-overflow", - "version": "0.1.7", + "version": "0.1.8-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md b/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md index 94001990b9..c315132091 100644 --- a/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md +++ b/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-tech-insights-backend-module-jsonfc +## 0.1.23-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/plugin-tech-insights-common@0.2.9-next.0 + - @backstage/plugin-tech-insights-node@0.3.7-next.0 + ## 0.1.22 ### Patch Changes diff --git a/plugins/tech-insights-backend-module-jsonfc/package.json b/plugins/tech-insights-backend-module-jsonfc/package.json index 0b344a4d04..3d62c81e96 100644 --- a/plugins/tech-insights-backend-module-jsonfc/package.json +++ b/plugins/tech-insights-backend-module-jsonfc/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights-backend-module-jsonfc", - "version": "0.1.22", + "version": "0.1.23-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/tech-insights-backend/CHANGELOG.md b/plugins/tech-insights-backend/CHANGELOG.md index 262cdfc764..fa416ea7ac 100644 --- a/plugins/tech-insights-backend/CHANGELOG.md +++ b/plugins/tech-insights-backend/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-tech-insights-backend +## 0.5.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/plugin-tech-insights-common@0.2.9-next.0 + - @backstage/plugin-tech-insights-node@0.3.7-next.0 + ## 0.5.4 ### Patch Changes diff --git a/plugins/tech-insights-backend/package.json b/plugins/tech-insights-backend/package.json index 6b3c50a6f1..fa573ae6c6 100644 --- a/plugins/tech-insights-backend/package.json +++ b/plugins/tech-insights-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights-backend", - "version": "0.5.4", + "version": "0.5.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/tech-insights-common/CHANGELOG.md b/plugins/tech-insights-common/CHANGELOG.md index 3ea396442e..97917ca063 100644 --- a/plugins/tech-insights-common/CHANGELOG.md +++ b/plugins/tech-insights-common/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-tech-insights-common +## 0.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.0.2-next.0 + ## 0.2.8 ### Patch Changes diff --git a/plugins/tech-insights-common/package.json b/plugins/tech-insights-common/package.json index 910fe5608c..7a11122a63 100644 --- a/plugins/tech-insights-common/package.json +++ b/plugins/tech-insights-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights-common", - "version": "0.2.8", + "version": "0.2.9-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/tech-insights-node/CHANGELOG.md b/plugins/tech-insights-node/CHANGELOG.md index 82d2c59f0f..53f8656181 100644 --- a/plugins/tech-insights-node/CHANGELOG.md +++ b/plugins/tech-insights-node/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-tech-insights-node +## 0.3.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/plugin-tech-insights-common@0.2.9-next.0 + ## 0.3.6 ### Patch Changes diff --git a/plugins/tech-insights-node/package.json b/plugins/tech-insights-node/package.json index b6f41aaa2e..7096496e3f 100644 --- a/plugins/tech-insights-node/package.json +++ b/plugins/tech-insights-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights-node", - "version": "0.3.6", + "version": "0.3.7-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/tech-insights/CHANGELOG.md b/plugins/tech-insights/CHANGELOG.md index 0066de5b0f..3415704918 100644 --- a/plugins/tech-insights/CHANGELOG.md +++ b/plugins/tech-insights/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-tech-insights +## 0.3.4-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-tech-insights-common@0.2.9-next.0 + ## 0.3.3 ### Patch Changes diff --git a/plugins/tech-insights/package.json b/plugins/tech-insights/package.json index 87b03646f9..48dd4362be 100644 --- a/plugins/tech-insights/package.json +++ b/plugins/tech-insights/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights", - "version": "0.3.3", + "version": "0.3.4-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/tech-radar/CHANGELOG.md b/plugins/tech-radar/CHANGELOG.md index 17025f1c85..36d1932684 100644 --- a/plugins/tech-radar/CHANGELOG.md +++ b/plugins/tech-radar/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-tech-radar +## 0.5.19-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/theme@0.2.16 + ## 0.5.18 ### Patch Changes diff --git a/plugins/tech-radar/package.json b/plugins/tech-radar/package.json index 689d9b22c8..599cb2db96 100644 --- a/plugins/tech-radar/package.json +++ b/plugins/tech-radar/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-tech-radar", "description": "A Backstage plugin that lets you display a Tech Radar for your organization", - "version": "0.5.18", + "version": "0.5.19-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/techdocs-addons-test-utils/CHANGELOG.md b/plugins/techdocs-addons-test-utils/CHANGELOG.md index dda684478d..70ad579f17 100644 --- a/plugins/techdocs-addons-test-utils/CHANGELOG.md +++ b/plugins/techdocs-addons-test-utils/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-techdocs-addons-test-utils +## 1.0.7-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/plugin-techdocs-react@1.0.7-next.0 + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-app-api@1.2.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration-react@1.1.7-next.0 + - @backstage/test-utils@1.2.3-next.0 + - @backstage/plugin-techdocs@1.4.1-next.0 + - @backstage/plugin-catalog@1.6.2-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-search-react@1.2.2-next.0 + ## 1.0.6 ### Patch Changes diff --git a/plugins/techdocs-addons-test-utils/package.json b/plugins/techdocs-addons-test-utils/package.json index 99367c07f1..2721ff9348 100644 --- a/plugins/techdocs-addons-test-utils/package.json +++ b/plugins/techdocs-addons-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-addons-test-utils", - "version": "1.0.6", + "version": "1.0.7-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/techdocs-backend/CHANGELOG.md b/plugins/techdocs-backend/CHANGELOG.md index 8965b8be7f..8c6f8ff66a 100644 --- a/plugins/techdocs-backend/CHANGELOG.md +++ b/plugins/techdocs-backend/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-techdocs-backend +## 1.4.2-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/plugin-permission-common@0.7.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/plugin-catalog-common@1.0.9-next.0 + - @backstage/plugin-search-common@1.1.2-next.0 + - @backstage/plugin-techdocs-node@1.4.3-next.0 + ## 1.4.1 ### Patch Changes diff --git a/plugins/techdocs-backend/package.json b/plugins/techdocs-backend/package.json index 35391ad2a9..c9f7364500 100644 --- a/plugins/techdocs-backend/package.json +++ b/plugins/techdocs-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs-backend", "description": "The Backstage backend plugin that renders technical documentation for your components", - "version": "1.4.1", + "version": "1.4.2-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/techdocs-module-addons-contrib/CHANGELOG.md b/plugins/techdocs-module-addons-contrib/CHANGELOG.md index 34d8ebacf1..8da781817a 100644 --- a/plugins/techdocs-module-addons-contrib/CHANGELOG.md +++ b/plugins/techdocs-module-addons-contrib/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-techdocs-module-addons-contrib +## 1.0.7-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- 8536e7c281: Use `app.title` from `app-config.yaml` when creating new Documentation Feedback issue. `Backstage` is the default value. +- Updated dependencies + - @backstage/plugin-techdocs-react@1.0.7-next.0 + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration-react@1.1.7-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/theme@0.2.16 + ## 1.0.6 ### Patch Changes diff --git a/plugins/techdocs-module-addons-contrib/package.json b/plugins/techdocs-module-addons-contrib/package.json index 8ad7811de8..beb5a8ddf1 100644 --- a/plugins/techdocs-module-addons-contrib/package.json +++ b/plugins/techdocs-module-addons-contrib/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs-module-addons-contrib", "description": "Plugin module for contributed TechDocs Addons", - "version": "1.0.6", + "version": "1.0.7-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/techdocs-node/CHANGELOG.md b/plugins/techdocs-node/CHANGELOG.md index 1fad63a9a1..981eff2be9 100644 --- a/plugins/techdocs-node/CHANGELOG.md +++ b/plugins/techdocs-node/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-techdocs-node +## 1.4.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/plugin-search-common@1.1.2-next.0 + ## 1.4.2 ### Patch Changes diff --git a/plugins/techdocs-node/package.json b/plugins/techdocs-node/package.json index 7da0d65167..6c52c31110 100644 --- a/plugins/techdocs-node/package.json +++ b/plugins/techdocs-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs-node", "description": "Common node.js functionalities for TechDocs, to be shared between techdocs-backend plugin and techdocs-cli", - "version": "1.4.2", + "version": "1.4.3-next.0", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/plugins/techdocs-react/CHANGELOG.md b/plugins/techdocs-react/CHANGELOG.md index 262c7f5284..ebea38b85e 100644 --- a/plugins/techdocs-react/CHANGELOG.md +++ b/plugins/techdocs-react/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-techdocs-react +## 1.0.7-next.0 + +### Patch Changes + +- cb716004ef: Internal refactor to improve tests +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/version-bridge@1.0.2 + ## 1.0.6 ### Patch Changes diff --git a/plugins/techdocs-react/package.json b/plugins/techdocs-react/package.json index 3adc83c969..c2334785ff 100644 --- a/plugins/techdocs-react/package.json +++ b/plugins/techdocs-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs-react", "description": "Shared frontend utilities for TechDocs and Addons", - "version": "1.0.6", + "version": "1.0.7-next.0", "publishConfig": { "access": "public", "alphaTypes": "dist/index.alpha.d.ts", diff --git a/plugins/techdocs/CHANGELOG.md b/plugins/techdocs/CHANGELOG.md index 8bbf00e84d..0757d6d1ce 100644 --- a/plugins/techdocs/CHANGELOG.md +++ b/plugins/techdocs/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-techdocs +## 1.4.1-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/plugin-techdocs-react@1.0.7-next.0 + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration-react@1.1.7-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-search-common@1.1.2-next.0 + - @backstage/plugin-search-react@1.2.2-next.0 + ## 1.4.0 ### Minor Changes diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index a7e7b4bd32..ac1efbe5f7 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs", "description": "The Backstage plugin that renders technical documentation for your components", - "version": "1.4.0", + "version": "1.4.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/todo-backend/CHANGELOG.md b/plugins/todo-backend/CHANGELOG.md index 0acae327c1..59864387e3 100644 --- a/plugins/todo-backend/CHANGELOG.md +++ b/plugins/todo-backend/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-todo-backend +## 0.1.36-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/catalog-client@1.2.0-next.0 + - @backstage/backend-common@0.16.1-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + ## 0.1.35 ### Patch Changes diff --git a/plugins/todo-backend/package.json b/plugins/todo-backend/package.json index 98e738bdd8..fd563c6a2e 100644 --- a/plugins/todo-backend/package.json +++ b/plugins/todo-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-todo-backend", "description": "A Backstage backend plugin that lets you browse TODO comments in your source code", - "version": "0.1.35", + "version": "0.1.36-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/todo/CHANGELOG.md b/plugins/todo/CHANGELOG.md index f05b2c3d4d..3197a6ac95 100644 --- a/plugins/todo/CHANGELOG.md +++ b/plugins/todo/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-todo +## 0.2.14-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + ## 0.2.13 ### Patch Changes diff --git a/plugins/todo/package.json b/plugins/todo/package.json index f5c4816b29..3247464afb 100644 --- a/plugins/todo/package.json +++ b/plugins/todo/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-todo", "description": "A Backstage plugin that lets you browse TODO comments in your source code", - "version": "0.2.13", + "version": "0.2.14-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/user-settings-backend/CHANGELOG.md b/plugins/user-settings-backend/CHANGELOG.md index f17baf793d..c0bb920fce 100644 --- a/plugins/user-settings-backend/CHANGELOG.md +++ b/plugins/user-settings-backend/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-user-settings-backend +## 0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/plugin-auth-node@0.2.8-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + ## 0.1.2 ### Patch Changes diff --git a/plugins/user-settings-backend/package.json b/plugins/user-settings-backend/package.json index 94a9c01d55..4f9d278cdf 100644 --- a/plugins/user-settings-backend/package.json +++ b/plugins/user-settings-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-user-settings-backend", "description": "The Backstage backend plugin to manage user settings", - "version": "0.1.2", + "version": "0.1.3-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/user-settings/CHANGELOG.md b/plugins/user-settings/CHANGELOG.md index ff36b363d8..c9c2effcad 100644 --- a/plugins/user-settings/CHANGELOG.md +++ b/plugins/user-settings/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-user-settings +## 0.6.0-next.0 + +### Minor Changes + +- 29bdda5442: Added the ability to fully customize settings page. Deprecated UserSettingsTab in favour of SettingsLayout.Route + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- 19356df560: Updated dependency `zen-observable` to `^0.9.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-app-api@1.2.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + ## 0.5.1 ### Patch Changes diff --git a/plugins/user-settings/package.json b/plugins/user-settings/package.json index 36c08ad872..e0b1822a9c 100644 --- a/plugins/user-settings/package.json +++ b/plugins/user-settings/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-user-settings", "description": "A Backstage plugin that provides a settings page", - "version": "0.5.1", + "version": "0.6.0-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/vault-backend/CHANGELOG.md b/plugins/vault-backend/CHANGELOG.md index 08fb5bf341..8b41bafb81 100644 --- a/plugins/vault-backend/CHANGELOG.md +++ b/plugins/vault-backend/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-vault-backend +## 0.2.5-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- 7a3d2688ed: Use `express-promise-router` to catch errors properly. + Add `403` error as a known one. It will now return a `NotAllowed` error. +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/backend-test-utils@0.1.31-next.0 + - @backstage/backend-tasks@0.3.8-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + ## 0.2.4 ### Patch Changes diff --git a/plugins/vault-backend/package.json b/plugins/vault-backend/package.json index 970c1a588a..7a5b7894dc 100644 --- a/plugins/vault-backend/package.json +++ b/plugins/vault-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-vault-backend", "description": "A Backstage backend plugin that integrates towards Vault", - "version": "0.2.4", + "version": "0.2.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/vault/CHANGELOG.md b/plugins/vault/CHANGELOG.md index 6f7da110d1..cc67baf940 100644 --- a/plugins/vault/CHANGELOG.md +++ b/plugins/vault/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-vault +## 0.1.6-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + ## 0.1.5 ### Patch Changes diff --git a/plugins/vault/package.json b/plugins/vault/package.json index ad508d978f..3dde73660f 100644 --- a/plugins/vault/package.json +++ b/plugins/vault/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-vault", "description": "A Backstage plugin that integrates towards Vault", - "version": "0.1.5", + "version": "0.1.6-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/xcmetrics/CHANGELOG.md b/plugins/xcmetrics/CHANGELOG.md index a4fccd2e16..4fee3c2c3f 100644 --- a/plugins/xcmetrics/CHANGELOG.md +++ b/plugins/xcmetrics/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-xcmetrics +## 0.2.32-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + ## 0.2.31 ### Patch Changes diff --git a/plugins/xcmetrics/package.json b/plugins/xcmetrics/package.json index 01e3467de8..db33c63d92 100644 --- a/plugins/xcmetrics/package.json +++ b/plugins/xcmetrics/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-xcmetrics", "description": "A Backstage plugin that shows XCode build metrics for your components", - "version": "0.2.31", + "version": "0.2.32-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/yarn.lock b/yarn.lock index 8e941eb7cb..eaea0493c3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3078,6 +3078,17 @@ __metadata: languageName: unknown linkType: soft +"@backstage/catalog-client@npm:^1.1.2": + version: 1.1.2 + resolution: "@backstage/catalog-client@npm:1.1.2" + dependencies: + "@backstage/catalog-model": ^1.1.3 + "@backstage/errors": ^1.1.3 + cross-fetch: ^3.1.5 + checksum: 1f57de39d9122cb104283ab8c0d107a40148d4cd0d7a2c012013851682831810df2cae204090d0d1382b7cd82a801b930e2c653b77df97f134d8e746a9e63900 + languageName: node + linkType: hard + "@backstage/catalog-client@workspace:^, @backstage/catalog-client@workspace:packages/catalog-client": version: 0.0.0-use.local resolution: "@backstage/catalog-client@workspace:packages/catalog-client" @@ -3090,7 +3101,22 @@ __metadata: languageName: unknown linkType: soft -"@backstage/catalog-model@^1.1.2, @backstage/catalog-model@workspace:^, @backstage/catalog-model@workspace:packages/catalog-model": +"@backstage/catalog-model@npm:^1.1.2, @backstage/catalog-model@npm:^1.1.3": + version: 1.1.3 + resolution: "@backstage/catalog-model@npm:1.1.3" + dependencies: + "@backstage/config": ^1.0.4 + "@backstage/errors": ^1.1.3 + "@backstage/types": ^1.0.1 + ajv: ^8.10.0 + json-schema: ^0.4.0 + lodash: ^4.17.21 + uuid: ^8.0.0 + checksum: 51e6821be44201d012550d7429cf4dc278fdd7dc001f4f5f6339a44a7e4dc155fbd44105d0dd96ea07b409fe93cd113a5a67370a758dfd368ab7b8e18d37ee6a + languageName: node + linkType: hard + +"@backstage/catalog-model@workspace:^, @backstage/catalog-model@workspace:packages/catalog-model": version: 0.0.0-use.local resolution: "@backstage/catalog-model@workspace:packages/catalog-model" dependencies: @@ -3304,7 +3330,17 @@ __metadata: languageName: unknown linkType: soft -"@backstage/config@^1.0.3, @backstage/config@workspace:^, @backstage/config@workspace:packages/config": +"@backstage/config@npm:^1.0.3, @backstage/config@npm:^1.0.4": + version: 1.0.4 + resolution: "@backstage/config@npm:1.0.4" + dependencies: + "@backstage/types": ^1.0.1 + lodash: ^4.17.21 + checksum: f18e1afa024a752fc2667e2d0e54eadedfab231d9346a0fc8f8c0a5a5c04138ac1814209d89b43ec50f14309a76ad77f16213116675122fecc00bf085236d83e + languageName: node + linkType: hard + +"@backstage/config@workspace:^, @backstage/config@workspace:packages/config": version: 0.0.0-use.local resolution: "@backstage/config@workspace:packages/config" dependencies: @@ -3401,6 +3437,57 @@ __metadata: languageName: node linkType: hard +"@backstage/core-components@npm:^0.12.0": + version: 0.12.0 + resolution: "@backstage/core-components@npm:0.12.0" + dependencies: + "@backstage/config": ^1.0.4 + "@backstage/core-plugin-api": ^1.1.0 + "@backstage/errors": ^1.1.3 + "@backstage/theme": ^0.2.16 + "@backstage/version-bridge": ^1.0.2 + "@material-table/core": ^3.1.0 + "@material-ui/core": ^4.12.2 + "@material-ui/icons": ^4.9.1 + "@material-ui/lab": 4.0.0-alpha.57 + "@react-hookz/web": ^15.0.0 + "@types/react-sparklines": ^1.7.0 + "@types/react-text-truncate": ^0.14.0 + ansi-regex: ^6.0.1 + classnames: ^2.2.6 + d3-selection: ^3.0.0 + d3-shape: ^3.0.0 + d3-zoom: ^3.0.0 + dagre: ^0.8.5 + history: ^5.0.0 + immer: ^9.0.1 + lodash: ^4.17.21 + pluralize: ^8.0.0 + prop-types: ^15.7.2 + qs: ^6.9.4 + rc-progress: 3.4.0 + react-helmet: 6.1.0 + react-hook-form: ^7.12.2 + react-markdown: ^8.0.0 + react-sparklines: ^1.7.0 + react-syntax-highlighter: ^15.4.5 + react-text-truncate: ^0.19.0 + react-use: ^17.3.2 + react-virtualized-auto-sizer: ^1.0.6 + react-window: ^1.8.6 + remark-gfm: ^3.0.1 + zen-observable: ^0.8.15 + zod: ^3.11.6 + peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 + react: ^16.13.1 || ^17.0.0 + react-dom: ^16.13.1 || ^17.0.0 + react-router: 6.0.0-beta.0 || ^6.3.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 + checksum: d113d62942b33b0a1290caf7ae73b223e88eb8a91c206be9a598dd4abd103faeec747dec76145af33e7e7ceb5209fdeefb507cbc21d8260681d15c449c005440 + languageName: node + linkType: hard + "@backstage/core-components@workspace:^, @backstage/core-components@workspace:packages/core-components": version: 0.0.0-use.local resolution: "@backstage/core-components@workspace:packages/core-components" @@ -3473,7 +3560,25 @@ __metadata: languageName: unknown linkType: soft -"@backstage/core-plugin-api@^1.0.7, @backstage/core-plugin-api@workspace:^, @backstage/core-plugin-api@workspace:packages/core-plugin-api": +"@backstage/core-plugin-api@npm:^1.0.7, @backstage/core-plugin-api@npm:^1.1.0": + version: 1.1.0 + resolution: "@backstage/core-plugin-api@npm:1.1.0" + dependencies: + "@backstage/config": ^1.0.4 + "@backstage/types": ^1.0.1 + "@backstage/version-bridge": ^1.0.2 + history: ^5.0.0 + prop-types: ^15.7.2 + zen-observable: ^0.8.15 + peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 + react: ^16.13.1 || ^17.0.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 + checksum: e63d6ac2bcaa0678f3051c3f9e91dfbb302c16b25c01bf9b463f01aeda309aca616fc482774f0c7cc1ecf91647bcd2b4899a58712b71785831d3be62d3ff58f6 + languageName: node + linkType: hard + +"@backstage/core-plugin-api@workspace:^, @backstage/core-plugin-api@workspace:packages/core-plugin-api": version: 0.0.0-use.local resolution: "@backstage/core-plugin-api@workspace:packages/core-plugin-api" dependencies: @@ -3559,7 +3664,18 @@ __metadata: languageName: unknown linkType: soft -"@backstage/errors@^1.1.2, @backstage/errors@workspace:^, @backstage/errors@workspace:packages/errors": +"@backstage/errors@npm:^1.1.2, @backstage/errors@npm:^1.1.3": + version: 1.1.3 + resolution: "@backstage/errors@npm:1.1.3" + dependencies: + "@backstage/types": ^1.0.1 + cross-fetch: ^3.1.5 + serialize-error: ^8.0.1 + checksum: 7d5d68ea79c179557f494fd83e9e457621d417d2b785378c8494ab441271cf541f4c0952f5afcb8dade1a51e715c5da5d926ed3154af54868b60b6c1d4cc0cf4 + languageName: node + linkType: hard + +"@backstage/errors@workspace:^, @backstage/errors@workspace:packages/errors": version: 0.0.0-use.local resolution: "@backstage/errors@workspace:packages/errors" dependencies: @@ -3570,7 +3686,26 @@ __metadata: languageName: unknown linkType: soft -"@backstage/integration-react@^1.1.5, @backstage/integration-react@workspace:^, @backstage/integration-react@workspace:packages/integration-react": +"@backstage/integration-react@npm:^1.1.5": + version: 1.1.6 + resolution: "@backstage/integration-react@npm:1.1.6" + dependencies: + "@backstage/config": ^1.0.4 + "@backstage/core-components": ^0.12.0 + "@backstage/core-plugin-api": ^1.1.0 + "@backstage/integration": ^1.4.0 + "@backstage/theme": ^0.2.16 + "@material-ui/core": ^4.12.2 + "@material-ui/icons": ^4.9.1 + "@material-ui/lab": 4.0.0-alpha.57 + react-use: ^17.2.4 + peerDependencies: + react: ^16.13.1 || ^17.0.0 + checksum: d46bad383db0453fe5c2dc4a941c6b4aae7b519cc72e740259f9c34ebe295e6f62797ac6a1598c3babae015bd3666a94a4a8f684ee311aa86c00aec30a065e98 + languageName: node + linkType: hard + +"@backstage/integration-react@workspace:^, @backstage/integration-react@workspace:packages/integration-react": version: 0.0.0-use.local resolution: "@backstage/integration-react@workspace:packages/integration-react" dependencies: @@ -3597,6 +3732,22 @@ __metadata: languageName: unknown linkType: soft +"@backstage/integration@npm:^1.4.0": + version: 1.4.0 + resolution: "@backstage/integration@npm:1.4.0" + dependencies: + "@backstage/config": ^1.0.4 + "@backstage/errors": ^1.1.3 + "@octokit/auth-app": ^4.0.0 + "@octokit/rest": ^19.0.3 + cross-fetch: ^3.1.5 + git-url-parse: ^13.0.0 + lodash: ^4.17.21 + luxon: ^3.0.0 + checksum: 69ca3c99c96ca840990bfeedbc7099f39668bafdc11298bb74000473efd49b5b43d9ad610adcef2635bfdaaa8eb0f6381413ee43d32a5a9725dccc020bada177 + languageName: node + linkType: hard + "@backstage/integration@workspace:^, @backstage/integration@workspace:packages/integration": version: 0.0.0-use.local resolution: "@backstage/integration@workspace:packages/integration" @@ -4619,7 +4770,18 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-catalog-common@^1.0.7, @backstage/plugin-catalog-common@workspace:^, @backstage/plugin-catalog-common@workspace:plugins/catalog-common": +"@backstage/plugin-catalog-common@npm:^1.0.7, @backstage/plugin-catalog-common@npm:^1.0.8": + version: 1.0.8 + resolution: "@backstage/plugin-catalog-common@npm:1.0.8" + dependencies: + "@backstage/catalog-model": ^1.1.3 + "@backstage/plugin-permission-common": ^0.7.1 + "@backstage/plugin-search-common": ^1.1.1 + checksum: bcf05d3b05bfb6662b350e6168c6eae8d57b8ed0f4dcd029eac5b48ce87ffa424708f9cdf54f6ff3fc43c094b6553508d53a1bc74a4fad49a1766e1d1bca0b5d + languageName: node + linkType: hard + +"@backstage/plugin-catalog-common@workspace:^, @backstage/plugin-catalog-common@workspace:plugins/catalog-common": version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-common@workspace:plugins/catalog-common" dependencies: @@ -4747,7 +4909,41 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-catalog-react@^1.2.0, @backstage/plugin-catalog-react@workspace:^, @backstage/plugin-catalog-react@workspace:plugins/catalog-react": +"@backstage/plugin-catalog-react@npm:^1.2.0, @backstage/plugin-catalog-react@npm:^1.2.1": + version: 1.2.1 + resolution: "@backstage/plugin-catalog-react@npm:1.2.1" + dependencies: + "@backstage/catalog-client": ^1.1.2 + "@backstage/catalog-model": ^1.1.3 + "@backstage/core-components": ^0.12.0 + "@backstage/core-plugin-api": ^1.1.0 + "@backstage/errors": ^1.1.3 + "@backstage/integration": ^1.4.0 + "@backstage/plugin-catalog-common": ^1.0.8 + "@backstage/plugin-permission-common": ^0.7.1 + "@backstage/plugin-permission-react": ^0.4.7 + "@backstage/theme": ^0.2.16 + "@backstage/types": ^1.0.1 + "@backstage/version-bridge": ^1.0.2 + "@material-ui/core": ^4.12.2 + "@material-ui/icons": ^4.9.1 + "@material-ui/lab": 4.0.0-alpha.57 + classnames: ^2.2.6 + jwt-decode: ^3.1.0 + lodash: ^4.17.21 + qs: ^6.9.4 + react-use: ^17.2.4 + yaml: ^2.0.0 + zen-observable: ^0.8.15 + peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 + react: ^16.13.1 || ^17.0.0 + react-router: 6.0.0-beta.0 || ^6.3.0 + checksum: 623103b7cb8cc4f08edb31b79e46d04e5f2eb27e6d95421430da4a9d1a18e74dc4aabc3d7c9e2ff15c615f6881b6a2e35fb953abe0bac7a8b93ec47d65432517 + languageName: node + linkType: hard + +"@backstage/plugin-catalog-react@workspace:^, @backstage/plugin-catalog-react@workspace:plugins/catalog-react": version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-react@workspace:plugins/catalog-react" dependencies: @@ -5767,7 +5963,31 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-home@^0.4.26, @backstage/plugin-home@workspace:^, @backstage/plugin-home@workspace:plugins/home": +"@backstage/plugin-home@npm:^0.4.26, @backstage/plugin-home@npm:^0.4.27": + version: 0.4.27 + resolution: "@backstage/plugin-home@npm:0.4.27" + dependencies: + "@backstage/catalog-model": ^1.1.3 + "@backstage/config": ^1.0.4 + "@backstage/core-components": ^0.12.0 + "@backstage/core-plugin-api": ^1.1.0 + "@backstage/plugin-catalog-react": ^1.2.1 + "@backstage/plugin-stack-overflow": ^0.1.7 + "@backstage/theme": ^0.2.16 + "@material-ui/core": ^4.12.2 + "@material-ui/icons": ^4.9.1 + "@material-ui/lab": 4.0.0-alpha.57 + lodash: ^4.17.21 + react-use: ^17.2.4 + peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 + react: ^16.13.1 || ^17.0.0 + react-router: 6.0.0-beta.0 || ^6.3.0 + checksum: 294dfe9ea8e59cef24fe71051f61ab46ee0eb140bc26828e9daa677265394a82ba869729401d898bff1b430a972131190ca98c0c4e5e15e503995332b25c02c0 + languageName: node + linkType: hard + +"@backstage/plugin-home@workspace:^, @backstage/plugin-home@workspace:plugins/home": version: 0.0.0-use.local resolution: "@backstage/plugin-home@workspace:plugins/home" dependencies: @@ -6304,6 +6524,20 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-permission-common@npm:^0.7.1": + version: 0.7.1 + resolution: "@backstage/plugin-permission-common@npm:0.7.1" + dependencies: + "@backstage/config": ^1.0.4 + "@backstage/errors": ^1.1.3 + "@backstage/types": ^1.0.1 + cross-fetch: ^3.1.5 + uuid: ^8.0.0 + zod: ^3.11.6 + checksum: d0ed7f8f3ed4163087db140f46e0fd055cc85e8127c0b26b17a595801df4dc0fa21330513f782be75e10cffb64c5f42f82b541b669e46e63113c41052277b65e + languageName: node + linkType: hard + "@backstage/plugin-permission-common@workspace:^, @backstage/plugin-permission-common@workspace:plugins/permission-common": version: 0.0.0-use.local resolution: "@backstage/plugin-permission-common@workspace:plugins/permission-common" @@ -6341,6 +6575,24 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-permission-react@npm:^0.4.7": + version: 0.4.7 + resolution: "@backstage/plugin-permission-react@npm:0.4.7" + dependencies: + "@backstage/config": ^1.0.4 + "@backstage/core-plugin-api": ^1.1.0 + "@backstage/plugin-permission-common": ^0.7.1 + cross-fetch: ^3.1.5 + react-use: ^17.2.4 + swr: ^1.1.2 + peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 + react: ^16.13.1 || ^17.0.0 + react-router: 6.0.0-beta.0 || ^6.3.0 + checksum: 4fac3ea7ac33012bf0690f6a4813ec63ea96c0e145a125012f1174a3b93cac84cc803854fe2f85735d84f29a6d11ee1f97391f6551b1a7907d62cb2351dc16be + languageName: node + linkType: hard + "@backstage/plugin-permission-react@workspace:^, @backstage/plugin-permission-react@workspace:plugins/permission-react": version: 0.0.0-use.local resolution: "@backstage/plugin-permission-react@workspace:plugins/permission-react" @@ -6821,6 +7073,16 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-search-common@npm:^1.1.1": + version: 1.1.1 + resolution: "@backstage/plugin-search-common@npm:1.1.1" + dependencies: + "@backstage/plugin-permission-common": ^0.7.1 + "@backstage/types": ^1.0.1 + checksum: 7c90229997c5545fe7ceca1fde7159b9f30339755551a7845e8ac628b640826793f300f820dfeb76bf6e57baf03a6469806b12f381e35bda373ca2e18374873e + languageName: node + linkType: hard + "@backstage/plugin-search-common@workspace:^, @backstage/plugin-search-common@workspace:plugins/search-common": version: 0.0.0-use.local resolution: "@backstage/plugin-search-common@workspace:plugins/search-common" @@ -7062,6 +7324,30 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-stack-overflow@npm:^0.1.7": + version: 0.1.7 + resolution: "@backstage/plugin-stack-overflow@npm:0.1.7" + dependencies: + "@backstage/config": ^1.0.4 + "@backstage/core-components": ^0.12.0 + "@backstage/core-plugin-api": ^1.1.0 + "@backstage/plugin-home": ^0.4.27 + "@backstage/plugin-search-common": ^1.1.1 + "@backstage/theme": ^0.2.16 + "@material-ui/core": ^4.12.2 + "@material-ui/icons": ^4.9.1 + "@testing-library/jest-dom": ^5.10.1 + cross-fetch: ^3.1.5 + lodash: ^4.17.21 + qs: ^6.9.4 + react-use: ^17.2.4 + peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 + react: ^16.13.1 || ^17.0.0 + checksum: 2e0bcba106cd042f4955b89ceabdd811dfa292a407e191330d9aa2e8e79d534dddc672db2cec02ca82831db50b24a1caeecf8dd45ff3b06408be679a46356eea + languageName: node + linkType: hard + "@backstage/plugin-stack-overflow@workspace:^, @backstage/plugin-stack-overflow@workspace:plugins/stack-overflow": version: 0.0.0-use.local resolution: "@backstage/plugin-stack-overflow@workspace:plugins/stack-overflow" @@ -7716,7 +8002,14 @@ __metadata: languageName: unknown linkType: soft -"@backstage/types@^1.0.0, @backstage/types@workspace:^, @backstage/types@workspace:packages/types": +"@backstage/types@npm:^1.0.0, @backstage/types@npm:^1.0.1": + version: 1.0.1 + resolution: "@backstage/types@npm:1.0.1" + checksum: 4857bc916f6afb77516fee565bb8048f2110425e32621ae7f332b9b9d32a738df26886b641339e811f3342488d44383c7a2fdd799de897b08fcca2062f1a9a13 + languageName: node + linkType: hard + +"@backstage/types@workspace:^, @backstage/types@workspace:packages/types": version: 0.0.0-use.local resolution: "@backstage/types@workspace:packages/types" dependencies: @@ -7727,7 +8020,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/version-bridge@^1.0.1, @backstage/version-bridge@workspace:^, @backstage/version-bridge@workspace:packages/version-bridge": +"@backstage/version-bridge@^1.0.1, @backstage/version-bridge@^1.0.2, @backstage/version-bridge@workspace:^, @backstage/version-bridge@workspace:packages/version-bridge": version: 0.0.0-use.local resolution: "@backstage/version-bridge@workspace:packages/version-bridge" dependencies: From 609b5ce65bdd0b46b68358ccd5e72f6596b2639a Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 22 Nov 2022 17:15:37 +0100 Subject: [PATCH 67/83] workflows,scripts: migrate to use GITHUB_OUTPUT Signed-off-by: Patrik Oldsberg --- .github/workflows/deploy_docker-image.yml | 2 +- .github/workflows/pr-review-comment.yaml | 2 +- .github/workflows/verify_docs-quality.yml | 2 +- scripts/check-if-release.js | 9 +++++++-- scripts/create-release-tag.js | 11 +++++++++-- 5 files changed, 19 insertions(+), 7 deletions(-) diff --git a/.github/workflows/deploy_docker-image.yml b/.github/workflows/deploy_docker-image.yml index e5564f141f..f5dc164737 100644 --- a/.github/workflows/deploy_docker-image.yml +++ b/.github/workflows/deploy_docker-image.yml @@ -44,7 +44,7 @@ jobs: - name: find location of global yarn cache id: yarn-cache if: steps.cache-modules.outputs.cache-hit != 'true' - run: echo "::set-output name=dir::$(yarn cache dir)" + run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT - name: cache global yarn cache uses: actions/cache@v3 diff --git a/.github/workflows/pr-review-comment.yaml b/.github/workflows/pr-review-comment.yaml index 6104a802d9..b51d73c4ad 100644 --- a/.github/workflows/pr-review-comment.yaml +++ b/.github/workflows/pr-review-comment.yaml @@ -33,7 +33,7 @@ jobs: } const prNumber = artifact.name.slice('pr_number-'.length) - console.log(`::set-output name=pr-number::${prNumber}`); + core.setOutput('pr-number', prNumber); - uses: backstage/actions/re-review@v0.5.7 with: diff --git a/.github/workflows/verify_docs-quality.yml b/.github/workflows/verify_docs-quality.yml index 736f09571f..dc1d942e32 100644 --- a/.github/workflows/verify_docs-quality.yml +++ b/.github/workflows/verify_docs-quality.yml @@ -18,7 +18,7 @@ jobs: # also contains an "--config=.github/vale/config.ini" option - name: generate vale args id: generate - run: echo "::set-output name=args::$(node scripts/check-docs-quality.js --ci-args)" + run: echo "args=$(node scripts/check-docs-quality.js --ci-args)" >> $GITHUB_OUTPUT - name: documentation quality check uses: errata-ai/vale-action@v2.0.1 diff --git a/scripts/check-if-release.js b/scripts/check-if-release.js index b61b0e2eb7..e7dabe14a4 100755 --- a/scripts/check-if-release.js +++ b/scripts/check-if-release.js @@ -28,6 +28,7 @@ const { execFile: execFileCb } = require('child_process'); const { resolve: resolvePath } = require('path'); const { promises: fs } = require('fs'); const { promisify } = require('util'); +const { EOL } = require('os'); const parentRef = process.env.COMMIT_SHA_BEFORE || 'HEAD^'; @@ -53,6 +54,10 @@ async function runPlain(cmd, ...args) { async function main() { process.cwd(resolvePath(__dirname, '..')); + if (!process.env.GITHUB_OUTPUT) { + throw new Error('GITHUB_OUTPUT environment variable not set'); + } + const diff = await runPlain( 'git', 'diff', @@ -103,7 +108,7 @@ async function main() { if (newVersions.length === 0) { console.log('No package version bumps detected, no release needed'); - console.log(`::set-output name=needs_release::false`); + await fs.appendFile(process.env.GITHUB_OUTPUT, `needs_release=false${EOL}`); return; } @@ -114,7 +119,7 @@ async function main() { ` ${name.padEnd(maxLength, ' ')} ${oldVersion} to ${newVersion}`, ); } - console.log(`::set-output name=needs_release::true`); + await fs.appendFile(process.env.GITHUB_OUTPUT, `needs_release=true${EOL}`); } main().catch(error => { diff --git a/scripts/create-release-tag.js b/scripts/create-release-tag.js index a2706c578f..28417024fd 100755 --- a/scripts/create-release-tag.js +++ b/scripts/create-release-tag.js @@ -19,6 +19,7 @@ const { Octokit } = require('@octokit/rest'); const path = require('path'); const fs = require('fs-extra'); +const { EOL } = require('os'); const baseOptions = { owner: 'backstage', @@ -64,6 +65,9 @@ async function main() { if (!process.env.GITHUB_TOKEN) { throw new Error('GITHUB_TOKEN is not set'); } + if (!process.env.GITHUB_OUTPUT) { + throw new Error('GITHUB_OUTPUT environment variable not set'); + } const commitSha = process.env.GITHUB_SHA; const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN }); @@ -74,8 +78,11 @@ async function main() { console.log(`Creating release tag ${tagName} at ${commitSha}`); await createGitTag(octokit, commitSha, tagName); - console.log(`::set-output name=tag_name::${tagName}`); - console.log(`::set-output name=version::${releaseVersion}`); + await fs.appendFile(process.env.GITHUB_OUTPUT, `tag_name=${tagName}${EOL}`); + await fs.appendFile( + process.env.GITHUB_OUTPUT, + `version=${releaseVersion}${EOL}`, + ); } main().catch(error => { From aa215809736631f5be22ae9c357765199f06385b Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 22 Nov 2022 17:21:41 +0100 Subject: [PATCH 68/83] scripts/patch-release-for-pr: exclude generated create-app changesets Signed-off-by: Patrik Oldsberg --- scripts/generate-merge-message.js | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/generate-merge-message.js b/scripts/generate-merge-message.js index 9b6fb5cbc6..6f579dfc20 100755 --- a/scripts/generate-merge-message.js +++ b/scripts/generate-merge-message.js @@ -31,6 +31,7 @@ async function hasNewChangesets(ref) { '--compact-summary', ref, '.changeset/*.md', + ':(exclude).changeset/create-app-*.md', ]); return stdout.includes('(new)'); } From 79db155e4d4eca5a8fc88523e6a3d057c54cd365 Mon Sep 17 00:00:00 2001 From: bnechyporenko Date: Tue, 22 Nov 2022 17:23:23 +0100 Subject: [PATCH 69/83] Cleaned up the code Signed-off-by: bnechyporenko --- plugins/cost-insights/src/testUtils/providers.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/plugins/cost-insights/src/testUtils/providers.tsx b/plugins/cost-insights/src/testUtils/providers.tsx index 1b3f8b29aa..46eab60163 100644 --- a/plugins/cost-insights/src/testUtils/providers.tsx +++ b/plugins/cost-insights/src/testUtils/providers.tsx @@ -31,11 +31,9 @@ import { ScrollContext, ScrollContextProps, } from '../hooks'; -import { Group, Duration } from '../types'; +import { Duration } from '../types'; import { createCurrencyFormat } from '../utils/currency'; -export const MockGroups: Group[] = [{ id: 'tech' }, { id: 'mock-group' }]; - export type MockFilterProviderProps = PropsWithChildren< Partial >; From 646d32e96de2c2133de586e539583b3d0d7280f3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 23 Nov 2022 00:35:56 +0000 Subject: [PATCH 70/83] Update dependency jose to v4.11.1 Signed-off-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 17baf94d94..f814935877 100644 --- a/yarn.lock +++ b/yarn.lock @@ -25614,9 +25614,9 @@ __metadata: linkType: hard "jose@npm:^4.10.0, jose@npm:^4.6.0": - version: 4.11.0 - resolution: "jose@npm:4.11.0" - checksum: 8d81e978e0da306911b61b1de1e2d78bd4903b4aa68a4b338b7c89c41edc3d56aea4d5ef4784a078a630dd6aa81f6328901ae3ce215f33b90d51ee8ebf4c9dbd + version: 4.11.1 + resolution: "jose@npm:4.11.1" + checksum: cd15cba258d0fd20f6168631ce2e94fda8442df80e43c1033c523915cecdf390a1cc8efe0eab0c2d65935ca973d791c668aea80724d2aa9c2879d4e70f3081d7 languageName: node linkType: hard From 4eb0bce2994e0c205790b3505833bfb3f84782d4 Mon Sep 17 00:00:00 2001 From: Patrick Jungermann Date: Wed, 23 Nov 2022 01:56:39 +0100 Subject: [PATCH 71/83] fix(catalog/bitbucketCloud,events): fix repo:push topic not matching `BitbucketCloudEventRouter` The sub-topic separator was changed from `/` to `.` as part of the change and review process at the original PR introducing this capability. Unfortunately, the adjustment at the entity provider was forgotten. Additionally, this change adds a few missing test for the `onEvent`/`onRepoPush` feature. Relates-to: PR #13931 Signed-off-by: Patrick Jungermann --- .changeset/stupid-gifts-serve.md | 5 + .../src/BitbucketCloudEntityProvider.test.ts | 387 +++++++++++++++--- .../src/BitbucketCloudEntityProvider.ts | 6 +- 3 files changed, 343 insertions(+), 55 deletions(-) create mode 100644 .changeset/stupid-gifts-serve.md diff --git a/.changeset/stupid-gifts-serve.md b/.changeset/stupid-gifts-serve.md new file mode 100644 index 0000000000..3110a1976c --- /dev/null +++ b/.changeset/stupid-gifts-serve.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-bitbucket-cloud': patch +--- + +Fix repo:push topic not matching `BitbucketCloudEventRouter`. diff --git a/plugins/catalog-backend-module-bitbucket-cloud/src/BitbucketCloudEntityProvider.test.ts b/plugins/catalog-backend-module-bitbucket-cloud/src/BitbucketCloudEntityProvider.test.ts index 72974a1c94..2856a26a13 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/src/BitbucketCloudEntityProvider.test.ts +++ b/plugins/catalog-backend-module-bitbucket-cloud/src/BitbucketCloudEntityProvider.test.ts @@ -14,18 +14,31 @@ * limitations under the License. */ -import { getVoidLogger } from '@backstage/backend-common'; +import { getVoidLogger, TokenManager } from '@backstage/backend-common'; import { PluginTaskScheduler, TaskInvocationDefinition, TaskRunner, } from '@backstage/backend-tasks'; -import { ConfigReader } from '@backstage/config'; -import { EntityProviderConnection } from '@backstage/plugin-catalog-backend'; import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; -import { BitbucketCloudEntityProvider } from './BitbucketCloudEntityProvider'; +import { CatalogApi } from '@backstage/catalog-client'; +import { + Entity, + LocationEntity, + stringifyEntityRef, +} from '@backstage/catalog-model'; +import { ConfigReader } from '@backstage/config'; +import { + EntityProviderConnection, + locationSpecToLocationEntity, +} from '@backstage/plugin-catalog-backend'; +import { Events } from '@backstage/plugin-bitbucket-cloud-common'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; +import { + ANNOTATION_BITBUCKET_CLOUD_REPO_URL, + BitbucketCloudEntityProvider, +} from './BitbucketCloudEntityProvider'; class PersistingTaskRunner implements TaskRunner { private tasks: TaskInvocationDefinition[] = []; @@ -38,6 +51,10 @@ class PersistingTaskRunner implements TaskRunner { this.tasks.push(task); return Promise.resolve(undefined); } + + reset() { + this.tasks = []; + } } const logger = getVoidLogger(); @@ -46,10 +63,103 @@ const server = setupServer(); describe('BitbucketCloudEntityProvider', () => { setupRequestMockHandlers(server); - afterEach(() => jest.resetAllMocks()); + + const simpleConfig = new ConfigReader({ + catalog: { + providers: { + bitbucketCloud: { + workspace: 'test-ws', + }, + }, + }, + }); + const defaultConfig = new ConfigReader({ + catalog: { + providers: { + bitbucketCloud: { + myProvider: { + workspace: 'test-ws', + catalogPath: 'catalog-custom.yaml', + filters: { + projectKey: 'test-.*', + repoSlug: 'test-.*', + }, + }, + }, + }, + }, + }); + const schedule = new PersistingTaskRunner(); + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + refresh: jest.fn(), + }; + const tokenManager = { + getToken: async () => { + return { token: 'fake-token' }; + }, + } as any as TokenManager; + const repoPushEvent: Events.RepoPushEvent = { + actor: { + type: 'user', + }, + repository: { + type: 'repository', + slug: 'test-repo', + links: { + html: { + href: 'https://bitbucket.org/test-ws/test-repo', + }, + }, + workspace: { + type: 'workspace', + slug: 'test-ws', + }, + project: { + type: 'project', + key: 'test-project', + }, + }, + push: { + changes: [ + // ... + ], + }, + }; + const repoPushEventParams = { + topic: 'bitbucketCloud.repo:push', + eventPayload: repoPushEvent, + metadata: { 'x-event-key': 'repo:push' }, + }; + + const createLocationEntity = ( + repoUrl: string, + branch: string, + targetPath: string, + ): LocationEntity => { + const target = `${repoUrl}/src/${branch}/${targetPath}`; + + const entity = locationSpecToLocationEntity({ + location: { + type: 'url', + target: target, + presence: 'required', + }, + }); + entity.metadata.annotations = { + ...entity.metadata.annotations, + [ANNOTATION_BITBUCKET_CLOUD_REPO_URL]: repoUrl, + }; + + return entity; + }; + + afterEach(() => { + jest.resetAllMocks(); + schedule.reset(); + }); it('no provider config', () => { - const schedule = new PersistingTaskRunner(); const config = new ConfigReader({}); const providers = BitbucketCloudEntityProvider.fromConfig(config, { logger, @@ -60,17 +170,7 @@ describe('BitbucketCloudEntityProvider', () => { }); it('single simple provider config', () => { - const schedule = new PersistingTaskRunner(); - const config = new ConfigReader({ - catalog: { - providers: { - bitbucketCloud: { - workspace: 'test-ws', - }, - }, - }, - }); - const providers = BitbucketCloudEntityProvider.fromConfig(config, { + const providers = BitbucketCloudEntityProvider.fromConfig(simpleConfig, { logger, schedule, }); @@ -82,18 +182,8 @@ describe('BitbucketCloudEntityProvider', () => { }); it('fail without schedule and scheduler', () => { - const config = new ConfigReader({ - catalog: { - providers: { - bitbucketCloud: { - workspace: 'test-ws', - }, - }, - }, - }); - expect(() => - BitbucketCloudEntityProvider.fromConfig(config, { + BitbucketCloudEntityProvider.fromConfig(simpleConfig, { logger, }), ).toThrow('Either schedule or scheduler must be provided.'); @@ -151,7 +241,6 @@ describe('BitbucketCloudEntityProvider', () => { }); it('multiple provider configs', () => { - const schedule = new PersistingTaskRunner(); const config = new ConfigReader({ catalog: { providers: { @@ -181,28 +270,7 @@ describe('BitbucketCloudEntityProvider', () => { }); it('apply full update on scheduled execution', async () => { - const config = new ConfigReader({ - catalog: { - providers: { - bitbucketCloud: { - myProvider: { - workspace: 'test-ws', - catalogPath: 'custom/path/catalog-custom.yaml', - filters: { - projectKey: 'test-.*', - repoSlug: 'test-.*', - }, - }, - }, - }, - }, - }); - const schedule = new PersistingTaskRunner(); - const entityProviderConnection: EntityProviderConnection = { - applyMutation: jest.fn(), - refresh: jest.fn(), - }; - const provider = BitbucketCloudEntityProvider.fromConfig(config, { + const provider = BitbucketCloudEntityProvider.fromConfig(defaultConfig, { logger, schedule, })[0]; @@ -354,4 +422,221 @@ describe('BitbucketCloudEntityProvider', () => { entities: expectedEntities, }); }); + + it('update onRepoPush', async () => { + const keptModule = createLocationEntity( + 'https://bitbucket.org/test-ws/test-repo', + 'main', + 'kept-module/catalog-custom.yaml', + ); + const removedModule = createLocationEntity( + 'https://bitbucket.org/test-ws/test-repo', + 'main', + 'removed-module/catalog-custom.yaml', + ); + const addedModule = createLocationEntity( + 'https://bitbucket.org/test-ws/test-repo', + 'main', + 'added-module/catalog-custom.yaml', + ); + + const catalogApi = { + getEntities: async ( + request: { filter: Record }, + options: { token: string }, + ): Promise<{ items: Entity[] }> => { + if ( + options.token !== 'fake-token' || + request.filter.kind !== 'Location' || + request.filter['metadata.annotations.bitbucket.org/repo-url'] !== + 'https://bitbucket.org/test-ws/test-repo' + ) { + return { items: [] }; + } + + return { + items: [keptModule, removedModule], + }; + }, + refreshEntity: jest.fn(), + }; + const provider = BitbucketCloudEntityProvider.fromConfig(defaultConfig, { + catalogApi: catalogApi as any as CatalogApi, + logger, + schedule, + tokenManager, + })[0]; + + server.use( + rest.get( + `https://api.bitbucket.org/2.0/workspaces/test-ws/search/code`, + (req, res, ctx) => { + const query = req.url.searchParams.get('search_query'); + if (!query || !query.includes('repo:test-repo')) { + return res(ctx.json({ values: [] })); + } + + const response = { + values: [ + { + path_matches: [ + { + match: true, + text: 'catalog-custom.yaml', + }, + ], + file: { + type: 'commit_file', + path: 'kept-module/catalog-custom.yaml', + commit: { + repository: { + slug: 'test-repo', + project: { + key: 'test-project', + }, + mainbranch: { + name: 'main', + }, + links: { + html: { + href: 'https://bitbucket.org/test-ws/test-repo', + }, + }, + }, + }, + }, + }, + { + path_matches: [ + { + match: true, + text: 'catalog-custom.yaml', + }, + ], + file: { + type: 'commit_file', + path: 'added-module/catalog-custom.yaml', + commit: { + repository: { + slug: 'test-repo', + project: { + key: 'test-project', + }, + mainbranch: { + name: 'main', + }, + links: { + html: { + href: 'https://bitbucket.org/test-ws/test-repo', + }, + }, + }, + }, + }, + }, + ], + }; + return res(ctx.json(response)); + }, + ), + ); + + await provider.connect(entityProviderConnection); + await provider.onEvent(repoPushEventParams); + + const addedEntities = [ + { + entity: addedModule, + locationKey: 'bitbucketCloud-provider:myProvider', + }, + ]; + const removedEntities = [ + { + entity: removedModule, + locationKey: 'bitbucketCloud-provider:myProvider', + }, + ]; + + expect(catalogApi.refreshEntity).toHaveBeenCalledTimes(1); + expect(catalogApi.refreshEntity).toHaveBeenCalledWith( + stringifyEntityRef(keptModule), + { token: 'fake-token' }, + ); + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(1); + expect(entityProviderConnection.applyMutation).toHaveBeenCalledWith({ + type: 'delta', + added: addedEntities, + removed: removedEntities, + }); + }); + + it('onRepoPush fail on incomplete setup', async () => { + const provider = BitbucketCloudEntityProvider.fromConfig(defaultConfig, { + logger, + schedule, + })[0]; + + await expect(provider.onEvent(repoPushEventParams)).rejects.toThrow( + 'bitbucketCloud-provider:myProvider not well configured to handle repo:push. Missing CatalogApi and/or TokenManager.', + ); + }); + + it('no onRepoPush update on non-matching workspace slug', async () => { + const catalogApi = { + getEntities: jest.fn(), + refreshEntity: jest.fn(), + }; + const provider = BitbucketCloudEntityProvider.fromConfig(defaultConfig, { + catalogApi: catalogApi as any as CatalogApi, + logger, + schedule, + tokenManager, + })[0]; + + await provider.connect(entityProviderConnection); + await provider.onEvent({ + ...repoPushEventParams, + eventPayload: { + ...repoPushEventParams.eventPayload, + repository: { + ...repoPushEventParams.eventPayload.repository, + workspace: { + ...repoPushEventParams.eventPayload.repository.workspace, + slug: 'not-matching', + }, + }, + }, + }); + + expect(catalogApi.refreshEntity).toHaveBeenCalledTimes(0); + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(0); + }); + + it('no onRepoPush update on non-matching repo slug', async () => { + const catalogApi = { + getEntities: jest.fn(), + refreshEntity: jest.fn(), + }; + const provider = BitbucketCloudEntityProvider.fromConfig(defaultConfig, { + catalogApi: catalogApi as any as CatalogApi, + logger, + schedule, + tokenManager, + })[0]; + + await provider.connect(entityProviderConnection); + await provider.onEvent({ + ...repoPushEventParams, + eventPayload: { + ...repoPushEventParams.eventPayload, + repository: { + ...repoPushEventParams.eventPayload.repository, + slug: 'not-matching', + }, + }, + }); + + expect(catalogApi.refreshEntity).toHaveBeenCalledTimes(0); + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(0); + }); }); diff --git a/plugins/catalog-backend-module-bitbucket-cloud/src/BitbucketCloudEntityProvider.ts b/plugins/catalog-backend-module-bitbucket-cloud/src/BitbucketCloudEntityProvider.ts index 37ad60426d..33b92589eb 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/src/BitbucketCloudEntityProvider.ts +++ b/plugins/catalog-backend-module-bitbucket-cloud/src/BitbucketCloudEntityProvider.ts @@ -49,7 +49,7 @@ import * as uuid from 'uuid'; import { Logger } from 'winston'; const DEFAULT_BRANCH = 'master'; -const TOPIC_REPO_PUSH = 'bitbucketCloud/repo:push'; +const TOPIC_REPO_PUSH = 'bitbucketCloud.repo:push'; /** @public */ export const ANNOTATION_BITBUCKET_CLOUD_REPO_URL = 'bitbucket.org/repo-url'; @@ -211,9 +211,7 @@ export class BitbucketCloudEntityProvider return; } - if (params.metadata?.['x-event-key'] === 'repo:push') { - await this.onRepoPush(params.eventPayload as Events.RepoPushEvent); - } + await this.onRepoPush(params.eventPayload as Events.RepoPushEvent); } private canHandleEvents(): boolean { From 3bd6cc7c554a38a7081830b7f737bb930a9b9bc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Mon, 21 Nov 2022 13:05:30 +0100 Subject: [PATCH 72/83] some more progress toward ubiquitous eslint-plugin-testing-library MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .eslintrc.js | 356 +++++++++--------- .../src/routing/FeatureFlagged.test.tsx | 18 +- .../AlertDisplay/AlertDisplay.test.tsx | 13 +- .../LogViewer/RealLogViewer.test.tsx | 4 +- .../SupportButton/SupportButton.test.tsx | 23 +- .../TabbedLayout/RoutedTabs.test.tsx | 13 +- .../TabbedLayout/TabbedLayout.test.tsx | 2 +- .../HeaderActionMenu.test.tsx | 4 +- .../PreparePullRequestForm.test.tsx | 2 +- .../StepPrepareSelectLocations.test.tsx | 4 +- .../UserListPicker/UserListPicker.test.tsx | 4 +- .../EntityLayout/EntityLayout.test.tsx | 6 +- .../EntityLinksCard/EntityLinksCard.test.tsx | 4 +- .../EntityLinksCard/IconLink.test.tsx | 2 +- .../EntityProcessingErrorsPanel.test.tsx | 2 +- .../EntitySwitch/EntitySwitch.test.tsx | 12 +- .../SystemDiagramCard.test.tsx | 4 +- .../src/components/BarChart/BarChart.test.tsx | 4 +- .../BarChart/BarChartLegend.test.tsx | 2 +- .../CostInsightsHeader.test.tsx | 15 +- .../PeriodSelect/PeriodSelect.test.tsx | 20 +- .../ProjectSelect/ProjectSelect.test.tsx | 18 +- .../CalendarCard/AttendeeChip.test.tsx | 16 +- .../CalendarCard/CalendarEvent.test.tsx | 36 +- .../CalendarEventPopoverContent.test.tsx | 27 +- .../AuditList/AuditListTable.test.tsx | 2 +- .../src/components/AuditView/index.test.tsx | 6 +- .../src/components/Intro/index.test.tsx | 6 +- .../components/Incident/Incidents.test.tsx | 39 +- .../CreatePlaylistButton.test.tsx | 3 +- .../EntityPlaylistDialog.test.tsx | 3 +- .../PersonalListPicker.test.tsx | 8 +- .../PlaylistEntitiesTable.test.tsx | 3 +- .../PlaylistPage/PlaylistHeader.test.tsx | 5 +- .../ActionsPage/ActionsPage.test.tsx | 24 +- .../ScaffolderPageContextMenu.test.tsx | 8 +- .../src/components/TaskPage/IconLink.test.tsx | 2 +- .../DryRunResults/DryRunResultsList.test.tsx | 8 +- .../TemplatePage/TemplatePage.test.tsx | 23 +- .../RegisterExistingButton.test.tsx | 20 +- .../Grids/EntityListDocsGrid.test.tsx | 12 +- 41 files changed, 390 insertions(+), 393 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 0257a2af1e..675a834efb 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -50,179 +50,191 @@ module.exports = { 'testing-library/no-await-sync-query': 'error', 'testing-library/prefer-wait-for': 'error', 'testing-library/no-dom-import': 'error', + 'testing-library/no-wait-for-side-effects': 'error', + 'testing-library/no-wait-for-empty-callback': 'error', 'no-restricted-globals': [ 'error', - 'postMessage', - 'blur', - 'focus', - 'close', - 'frames', - 'self', - 'parent', - 'opener', - 'top', - 'length', - 'closed', - 'location', - 'origin', - 'name', - 'locationbar', - 'menubar', - 'personalbar', - 'scrollbars', - 'statusbar', - 'toolbar', - 'status', - 'frameElement', - 'navigator', - 'customElements', - 'external', - 'screen', - 'innerWidth', - 'innerHeight', - 'scrollX', - 'pageXOffset', - 'scrollY', - 'pageYOffset', - 'screenX', - 'screenY', - 'outerWidth', - 'outerHeight', - 'devicePixelRatio', - 'clientInformation', - 'screenLeft', - 'screenTop', - 'defaultStatus', - 'defaultstatus', - 'styleMedia', - 'onanimationend', - 'onanimationiteration', - 'onanimationstart', - 'onsearch', - 'ontransitionend', - 'onwebkitanimationend', - 'onwebkitanimationiteration', - 'onwebkitanimationstart', - 'onwebkittransitionend', - 'isSecureContext', - 'onabort', - 'onblur', - 'oncancel', - 'oncanplay', - 'oncanplaythrough', - 'onchange', - 'onclick', - 'onclose', - 'oncontextmenu', - 'oncuechange', - 'ondblclick', - 'ondrag', - 'ondragend', - 'ondragenter', - 'ondragleave', - 'ondragover', - 'ondragstart', - 'ondrop', - 'ondurationchange', - 'onemptied', - 'onended', - 'onerror', - 'onfocus', - 'oninput', - 'oninvalid', - 'onkeydown', - 'onkeypress', - 'onkeyup', - 'onload', - 'onloadeddata', - 'onloadedmetadata', - 'onloadstart', - 'onmousedown', - 'onmouseenter', - 'onmouseleave', - 'onmousemove', - 'onmouseout', - 'onmouseover', - 'onmouseup', - 'onmousewheel', - 'onpause', - 'onplay', - 'onplaying', - 'onprogress', - 'onratechange', - 'onreset', - 'onresize', - 'onscroll', - 'onseeked', - 'onseeking', - 'onselect', - 'onstalled', - 'onsubmit', - 'onsuspend', - 'ontimeupdate', - 'ontoggle', - 'onvolumechange', - 'onwaiting', - 'onwheel', - 'onauxclick', - 'ongotpointercapture', - 'onlostpointercapture', - 'onpointerdown', - 'onpointermove', - 'onpointerup', - 'onpointercancel', - 'onpointerover', - 'onpointerout', - 'onpointerenter', - 'onpointerleave', - 'onafterprint', - 'onbeforeprint', - 'onbeforeunload', - 'onhashchange', - 'onlanguagechange', - 'onmessage', - 'onmessageerror', - 'onoffline', - 'ononline', - 'onpagehide', - 'onpageshow', - 'onpopstate', - 'onrejectionhandled', - 'onstorage', - 'onunhandledrejection', - 'onunload', - 'performance', - 'stop', - 'open', - 'print', - 'captureEvents', - 'releaseEvents', - 'getComputedStyle', - 'matchMedia', - 'moveTo', - 'moveBy', - 'resizeTo', - 'resizeBy', - 'getSelection', - 'find', - 'createImageBitmap', - 'scroll', - 'scrollTo', - 'scrollBy', - 'onappinstalled', - 'onbeforeinstallprompt', - 'crypto', - 'ondevicemotion', - 'ondeviceorientation', - 'ondeviceorientationabsolute', - 'indexedDB', - 'webkitStorageInfo', - 'chrome', - 'visualViewport', - 'speechSynthesis', - 'webkitRequestFileSystem', - 'webkitResolveLocalFileSystemURL', - 'openDatabase', - ], + [ + 'blur', + 'captureEvents', + 'chrome', + 'clientInformation', + 'close', + 'closed', + 'createImageBitmap', + 'crypto', + 'customElements', + 'defaultstatus', + 'defaultStatus', + 'devicePixelRatio', + 'external', + 'find', + 'focus', + 'frameElement', + 'frames', + 'getComputedStyle', + 'getSelection', + 'indexedDB', + 'innerHeight', + 'innerWidth', + 'isSecureContext', + 'length', + 'location', + 'locationbar', + 'matchMedia', + 'menubar', + 'moveBy', + 'moveTo', + 'name', + 'navigator', + 'onabort', + 'onafterprint', + 'onanimationend', + 'onanimationiteration', + 'onanimationstart', + 'onappinstalled', + 'onauxclick', + 'onbeforeinstallprompt', + 'onbeforeprint', + 'onbeforeunload', + 'onblur', + 'oncancel', + 'oncanplay', + 'oncanplaythrough', + 'onchange', + 'onclick', + 'onclose', + 'oncontextmenu', + 'oncuechange', + 'ondblclick', + 'ondevicemotion', + 'ondeviceorientation', + 'ondeviceorientationabsolute', + 'ondrag', + 'ondragend', + 'ondragenter', + 'ondragleave', + 'ondragover', + 'ondragstart', + 'ondrop', + 'ondurationchange', + 'onemptied', + 'onended', + 'onerror', + 'onfocus', + 'ongotpointercapture', + 'onhashchange', + 'oninput', + 'oninvalid', + 'onkeydown', + 'onkeypress', + 'onkeyup', + 'onlanguagechange', + 'onload', + 'onloadeddata', + 'onloadedmetadata', + 'onloadstart', + 'onlostpointercapture', + 'onmessage', + 'onmessageerror', + 'onmousedown', + 'onmouseenter', + 'onmouseleave', + 'onmousemove', + 'onmouseout', + 'onmouseover', + 'onmouseup', + 'onmousewheel', + 'onoffline', + 'ononline', + 'onpagehide', + 'onpageshow', + 'onpause', + 'onplay', + 'onplaying', + 'onpointercancel', + 'onpointerdown', + 'onpointerenter', + 'onpointerleave', + 'onpointermove', + 'onpointerout', + 'onpointerover', + 'onpointerup', + 'onpopstate', + 'onprogress', + 'onratechange', + 'onrejectionhandled', + 'onreset', + 'onresize', + 'onscroll', + 'onsearch', + 'onseeked', + 'onseeking', + 'onselect', + 'onstalled', + 'onstorage', + 'onsubmit', + 'onsuspend', + 'ontimeupdate', + 'ontoggle', + 'ontransitionend', + 'onunhandledrejection', + 'onunload', + 'onvolumechange', + 'onwaiting', + 'onwebkitanimationend', + 'onwebkitanimationiteration', + 'onwebkitanimationstart', + 'onwebkittransitionend', + 'onwheel', + 'open', + 'openDatabase', + 'opener', + 'origin', + 'outerHeight', + 'outerWidth', + 'pageXOffset', + 'pageYOffset', + 'parent', + 'performance', + 'personalbar', + 'postMessage', + 'print', + 'releaseEvents', + 'resizeBy', + 'resizeTo', + 'screen', + 'screenLeft', + 'screenTop', + 'screenX', + 'screenY', + 'scroll', + 'scrollbars', + 'scrollBy', + 'scrollTo', + 'scrollX', + 'scrollY', + 'self', + 'speechSynthesis', + 'status', + 'statusbar', + 'stop', + 'styleMedia', + 'toolbar', + 'top', + 'visualViewport', + 'webkitRequestFileSystem', + 'webkitResolveLocalFileSystemURL', + 'webkitStorageInfo', + ].map(function f(name) { + return { + name: name, + message: + 'Avoid using implicitly global variables. Use e.g. window.' + + name + + ' instead if this was your intent.', + }; + }), + ].flat(), }, }; diff --git a/packages/core-app-api/src/routing/FeatureFlagged.test.tsx b/packages/core-app-api/src/routing/FeatureFlagged.test.tsx index 410540f77e..8ee74c0a23 100644 --- a/packages/core-app-api/src/routing/FeatureFlagged.test.tsx +++ b/packages/core-app-api/src/routing/FeatureFlagged.test.tsx @@ -16,7 +16,7 @@ import React from 'react'; import { FeatureFlagged } from './FeatureFlagged'; -import { render } from '@testing-library/react'; +import { render, screen } from '@testing-library/react'; import { LocalStorageFeatureFlags } from '../apis'; import { TestApiProvider } from '@backstage/test-utils'; import { featureFlagsApiRef } from '@backstage/core-plugin-api'; @@ -35,7 +35,7 @@ describe('FeatureFlagged', () => { .spyOn(mockFeatureFlagsApi, 'isActive') .mockImplementation(() => true); - const { queryByText } = render( + render(

@@ -45,14 +45,14 @@ describe('FeatureFlagged', () => { , ); - expect(queryByText('BACKSTAGE!')).toBeInTheDocument(); + expect(screen.getByText('BACKSTAGE!')).toBeInTheDocument(); }); it('should not render contents when the feature flag is disabled', async () => { jest .spyOn(mockFeatureFlagsApi, 'isActive') .mockImplementation(() => false); - const { queryByText } = render( + render(
@@ -62,7 +62,7 @@ describe('FeatureFlagged', () => { , ); - expect(queryByText('BACKSTAGE!')).not.toBeInTheDocument(); + expect(screen.queryByText('BACKSTAGE!')).not.toBeInTheDocument(); }); }); describe('without', () => { @@ -71,7 +71,7 @@ describe('FeatureFlagged', () => { .spyOn(mockFeatureFlagsApi, 'isActive') .mockImplementation(() => true); - const { queryByText } = render( + render(
@@ -81,14 +81,14 @@ describe('FeatureFlagged', () => { , ); - expect(queryByText('BACKSTAGE!')).not.toBeInTheDocument(); + expect(screen.queryByText('BACKSTAGE!')).not.toBeInTheDocument(); }); it('should render contents when the feature flag is disabled', async () => { jest .spyOn(mockFeatureFlagsApi, 'isActive') .mockImplementation(() => false); - const { queryByText } = render( + render(
@@ -98,7 +98,7 @@ describe('FeatureFlagged', () => { , ); - expect(queryByText('BACKSTAGE!')).toBeInTheDocument(); + expect(screen.getByText('BACKSTAGE!')).toBeInTheDocument(); }); }); }); diff --git a/packages/core-components/src/components/AlertDisplay/AlertDisplay.test.tsx b/packages/core-components/src/components/AlertDisplay/AlertDisplay.test.tsx index 477057f31b..c366082b46 100644 --- a/packages/core-components/src/components/AlertDisplay/AlertDisplay.test.tsx +++ b/packages/core-components/src/components/AlertDisplay/AlertDisplay.test.tsx @@ -15,6 +15,7 @@ */ import React from 'react'; +import { screen } from '@testing-library/react'; import { AlertDisplay } from './AlertDisplay'; import { alertApiRef } from '@backstage/core-plugin-api'; import { AlertApiForwarder } from '@backstage/core-app-api'; @@ -34,7 +35,7 @@ describe('', () => { }); it('renders with message', async () => { - const { queryByText } = await renderInTestApp( + await renderInTestApp( ', () => { , ); - expect(queryByText(TEST_MESSAGE)).toBeInTheDocument(); + expect(screen.getByText(TEST_MESSAGE)).toBeInTheDocument(); }); describe('with multiple messages', () => { @@ -73,23 +74,23 @@ describe('', () => { ] as const; it('renders first message', async () => { - const { queryByText } = await renderInTestApp( + await renderInTestApp( , ); - expect(queryByText('message one')).toBeInTheDocument(); + expect(screen.getByText('message one')).toBeInTheDocument(); }); it('renders a count of remaining messages', async () => { - const { queryByText } = await renderInTestApp( + await renderInTestApp( , ); - expect(queryByText('(2 older messages)')).toBeInTheDocument(); + expect(screen.getByText('(2 older messages)')).toBeInTheDocument(); }); }); }); diff --git a/packages/core-components/src/components/LogViewer/RealLogViewer.test.tsx b/packages/core-components/src/components/LogViewer/RealLogViewer.test.tsx index b56279a53f..dd707778e1 100644 --- a/packages/core-components/src/components/LogViewer/RealLogViewer.test.tsx +++ b/packages/core-components/src/components/LogViewer/RealLogViewer.test.tsx @@ -60,11 +60,11 @@ describe('RealLogViewer', () => { await userEvent.keyboard('{shift>}{enter}{/shift}'); expect(rendered.getByText('3/3')).toBeInTheDocument(); - expect(rendered.queryByText('Some Log Line')).toBeInTheDocument(); + expect(rendered.getByText('Some Log Line')).toBeInTheDocument(); await userEvent.keyboard('{meta>}{enter}{/meta}'); expect(rendered.queryByText('Some Log Line')).not.toBeInTheDocument(); await userEvent.keyboard('{meta>}{enter}{/meta}'); - expect(rendered.queryByText('Some Log Line')).toBeInTheDocument(); + expect(rendered.getByText('Some Log Line')).toBeInTheDocument(); // Tab down to line #2 and click await userEvent.tab(); diff --git a/packages/core-components/src/components/SupportButton/SupportButton.test.tsx b/packages/core-components/src/components/SupportButton/SupportButton.test.tsx index 2907b24702..6b0e239aa5 100644 --- a/packages/core-components/src/components/SupportButton/SupportButton.test.tsx +++ b/packages/core-components/src/components/SupportButton/SupportButton.test.tsx @@ -14,15 +14,15 @@ * limitations under the License. */ -import React from 'react'; -import { fireEvent, screen } from '@testing-library/react'; +import { configApiRef } from '@backstage/core-plugin-api'; import { MockConfigApi, renderInTestApp, TestApiProvider, } from '@backstage/test-utils'; +import { act, fireEvent, screen } from '@testing-library/react'; +import React from 'react'; import { SupportButton } from './SupportButton'; -import { configApiRef } from '@backstage/core-plugin-api'; const configApi = new MockConfigApi({ app: { @@ -45,8 +45,9 @@ const POPOVER_ID = 'support-button-popover'; describe('', () => { it('renders without exploding', async () => { await renderInTestApp(); - - expect(screen.getByTestId(SUPPORT_BUTTON_ID)).toBeInTheDocument(); + await expect( + screen.findByTestId(SUPPORT_BUTTON_ID), + ).resolves.toBeInTheDocument(); }); it('supports passing a title', async () => { @@ -96,11 +97,13 @@ describe('', () => { it('shows popover on click', async () => { await renderInTestApp(); - const supportButton = screen.getByTestId(SUPPORT_BUTTON_ID); - expect(supportButton).toBeInTheDocument(); + await expect( + screen.findByTestId(SUPPORT_BUTTON_ID), + ).resolves.toBeInTheDocument(); + await act(async () => { + fireEvent.click(screen.getByTestId(SUPPORT_BUTTON_ID)); + }); - fireEvent.click(supportButton); - - expect(screen.getByTestId(POPOVER_ID)).toBeInTheDocument(); + await expect(screen.findByTestId(POPOVER_ID)).resolves.toBeInTheDocument(); }); }); diff --git a/packages/core-components/src/components/TabbedLayout/RoutedTabs.test.tsx b/packages/core-components/src/components/TabbedLayout/RoutedTabs.test.tsx index 15b00937a0..bbdb901f33 100644 --- a/packages/core-components/src/components/TabbedLayout/RoutedTabs.test.tsx +++ b/packages/core-components/src/components/TabbedLayout/RoutedTabs.test.tsx @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { renderInTestApp } from '@backstage/test-utils'; import { act, fireEvent } from '@testing-library/react'; import React from 'react'; @@ -65,14 +66,14 @@ describe('RoutedTabs', () => { expect(rendered.queryByText('tabbed-test-content')).not.toBeInTheDocument(); expect(rendered.getByText('tabbed-test-title-2')).toBeInTheDocument(); - expect(rendered.queryByText('tabbed-test-content-2')).toBeInTheDocument(); + expect(rendered.getByText('tabbed-test-content-2')).toBeInTheDocument(); const thirdTab = rendered.queryAllByRole('tab')[2]; act(() => { fireEvent.click(thirdTab); }); expect(rendered.getByText('tabbed-test-title-3')).toBeInTheDocument(); - expect(rendered.queryByText('tabbed-test-content-3')).toBeInTheDocument(); + expect(rendered.getByText('tabbed-test-content-3')).toBeInTheDocument(); }); describe('correctly delegates nested links', () => { @@ -113,9 +114,9 @@ describe('RoutedTabs', () => { expect( rendered.queryByText('tabbed-test-content'), ).not.toBeInTheDocument(); - expect(rendered.queryByText('tabbed-test-content-2')).toBeInTheDocument(); + expect(rendered.getByText('tabbed-test-content-2')).toBeInTheDocument(); expect( - rendered.queryByText('tabbed-test-nested-content-2'), + rendered.getByText('tabbed-test-nested-content-2'), ).toBeInTheDocument(); }); @@ -125,7 +126,7 @@ describe('RoutedTabs', () => { expect( rendered.queryByText('tabbed-test-content'), ).not.toBeInTheDocument(); - expect(rendered.queryByText('tabbed-test-content-2')).toBeInTheDocument(); + expect(rendered.getByText('tabbed-test-content-2')).toBeInTheDocument(); expect( rendered.queryByText('tabbed-test-nested-content-2'), ).not.toBeInTheDocument(); @@ -142,7 +143,7 @@ describe('RoutedTabs', () => { expect(rendered.queryByText('tabbed-test-content')).not.toBeInTheDocument(); expect(rendered.getByText('tabbed-test-title-2')).toBeInTheDocument(); - expect(rendered.queryByText('tabbed-test-content-2')).toBeInTheDocument(); + expect(rendered.getByText('tabbed-test-content-2')).toBeInTheDocument(); }); it('redirects to the top level when no route is matching the url', async () => { diff --git a/packages/core-components/src/components/TabbedLayout/TabbedLayout.test.tsx b/packages/core-components/src/components/TabbedLayout/TabbedLayout.test.tsx index e103fc2f46..b84a7f262d 100644 --- a/packages/core-components/src/components/TabbedLayout/TabbedLayout.test.tsx +++ b/packages/core-components/src/components/TabbedLayout/TabbedLayout.test.tsx @@ -79,6 +79,6 @@ describe('TabbedLayout', () => { expect(queryByText('tabbed-test-content')).not.toBeInTheDocument(); expect(getByText('tabbed-test-title-2')).toBeInTheDocument(); - expect(queryByText('tabbed-test-content-2')).toBeInTheDocument(); + expect(getByText('tabbed-test-content-2')).toBeInTheDocument(); }); }); diff --git a/packages/core-components/src/layout/HeaderActionMenu/HeaderActionMenu.test.tsx b/packages/core-components/src/layout/HeaderActionMenu/HeaderActionMenu.test.tsx index 92ce241aa8..b56ae3167f 100644 --- a/packages/core-components/src/layout/HeaderActionMenu/HeaderActionMenu.test.tsx +++ b/packages/core-components/src/layout/HeaderActionMenu/HeaderActionMenu.test.tsx @@ -43,7 +43,7 @@ describe('', () => { await fireEvent.click(rendered.queryByText('Some label') as Node); expect(onClickFunction).toHaveBeenCalled(); // We do not expect the dropdown to disappear after click - expect(rendered.queryByText('Some label')).toBeInTheDocument(); + expect(rendered.getByText('Some label')).toBeInTheDocument(); }); it('Disabled', async () => { @@ -80,7 +80,7 @@ describe('', () => { await fireEvent.click(rendered.queryByText('Secondary label') as Node); expect(onClickFunction).toHaveBeenCalled(); // We do not expect the dropdown to disappear after click - expect(rendered.queryByText('Some label')).toBeInTheDocument(); + expect(rendered.getByText('Some label')).toBeInTheDocument(); }); it('should close when hitting escape', async () => { diff --git a/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/PreparePullRequestForm.test.tsx b/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/PreparePullRequestForm.test.tsx index 02b67090fa..a8188ce358 100644 --- a/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/PreparePullRequestForm.test.tsx +++ b/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/PreparePullRequestForm.test.tsx @@ -110,7 +110,7 @@ describe('', () => { expect(onSubmitFn).not.toHaveBeenCalled(); expect( - screen.queryByText('Error in required main field'), + screen.getByText('Error in required main field'), ).toBeInTheDocument(); }); }); diff --git a/plugins/catalog-import/src/components/StepPrepareSelectLocations/StepPrepareSelectLocations.test.tsx b/plugins/catalog-import/src/components/StepPrepareSelectLocations/StepPrepareSelectLocations.test.tsx index 5a30c7735a..b5efd3fbbf 100644 --- a/plugins/catalog-import/src/components/StepPrepareSelectLocations/StepPrepareSelectLocations.test.tsx +++ b/plugins/catalog-import/src/components/StepPrepareSelectLocations/StepPrepareSelectLocations.test.tsx @@ -69,7 +69,7 @@ describe('', () => { expect(screen.getByText('url-1')).toBeInTheDocument(); expect(screen.getByText('url-2')).toBeInTheDocument(); expect( - screen.queryByText(/Select one or more locations/), + screen.getByText(/Select one or more locations/), ).toBeInTheDocument(); expect( screen.queryByText(/locations already exist/), @@ -104,7 +104,7 @@ describe('', () => { ); expect(screen.getByText(/my-target/)).toBeInTheDocument(); - expect(screen.queryByText(/locations already exist/)).toBeInTheDocument(); + expect(screen.getByText(/locations already exist/)).toBeInTheDocument(); expect( screen.queryByText(/Select one or more locations/), ).not.toBeInTheDocument(); diff --git a/plugins/catalog-react/src/components/UserListPicker/UserListPicker.test.tsx b/plugins/catalog-react/src/components/UserListPicker/UserListPicker.test.tsx index d5309a383d..c31381df20 100644 --- a/plugins/catalog-react/src/components/UserListPicker/UserListPicker.test.tsx +++ b/plugins/catalog-react/src/components/UserListPicker/UserListPicker.test.tsx @@ -151,8 +151,8 @@ describe('', () => { , ); - expect(screen.queryByText('Personal')).toBeInTheDocument(); - expect(screen.queryByText('Test Company')).toBeInTheDocument(); + expect(screen.getByText('Personal')).toBeInTheDocument(); + expect(screen.getByText('Test Company')).toBeInTheDocument(); }); it('renders filters', () => { diff --git a/plugins/catalog/src/components/EntityLayout/EntityLayout.test.tsx b/plugins/catalog/src/components/EntityLayout/EntityLayout.test.tsx index 980ce13109..08c751c6c6 100644 --- a/plugins/catalog/src/components/EntityLayout/EntityLayout.test.tsx +++ b/plugins/catalog/src/components/EntityLayout/EntityLayout.test.tsx @@ -190,7 +190,7 @@ describe('EntityLayout', () => { expect(screen.queryByText('tabbed-test-content')).not.toBeInTheDocument(); expect(screen.getByText('tabbed-test-title-2')).toBeInTheDocument(); - expect(screen.queryByText('tabbed-test-content-2')).toBeInTheDocument(); + expect(screen.getByText('tabbed-test-content-2')).toBeInTheDocument(); }); it('should conditionally render tabs', async () => { @@ -228,8 +228,8 @@ describe('EntityLayout', () => { }, ); - expect(screen.queryByText('tabbed-test-title')).toBeInTheDocument(); + expect(screen.getByText('tabbed-test-title')).toBeInTheDocument(); expect(screen.queryByText('tabbed-test-title-2')).not.toBeInTheDocument(); - expect(screen.queryByText('tabbed-test-title-3')).toBeInTheDocument(); + expect(screen.getByText('tabbed-test-title-3')).toBeInTheDocument(); }); }); diff --git a/plugins/catalog/src/components/EntityLinksCard/EntityLinksCard.test.tsx b/plugins/catalog/src/components/EntityLinksCard/EntityLinksCard.test.tsx index 6316bdbc85..304a962212 100644 --- a/plugins/catalog/src/components/EntityLinksCard/EntityLinksCard.test.tsx +++ b/plugins/catalog/src/components/EntityLinksCard/EntityLinksCard.test.tsx @@ -52,7 +52,7 @@ describe('EntityLinksCard', () => { ), ); - expect(screen.queryByText('admin dashboard')).toBeInTheDocument(); + expect(screen.getByText('admin dashboard')).toBeInTheDocument(); expect(screen.queryByText('derp')).not.toBeInTheDocument(); }); @@ -66,7 +66,7 @@ describe('EntityLinksCard', () => { ); expect( - screen.queryByText(/.*No links defined for this entity.*/), + screen.getByText(/.*No links defined for this entity.*/), ).toBeInTheDocument(); expect(screen.queryByText('admin dashboard')).not.toBeInTheDocument(); }); diff --git a/plugins/catalog/src/components/EntityLinksCard/IconLink.test.tsx b/plugins/catalog/src/components/EntityLinksCard/IconLink.test.tsx index 164e54a2eb..be784ae3e8 100644 --- a/plugins/catalog/src/components/EntityLinksCard/IconLink.test.tsx +++ b/plugins/catalog/src/components/EntityLinksCard/IconLink.test.tsx @@ -33,6 +33,6 @@ describe('IconLink', () => { , ); - expect(screen.queryByText('I am Link')).toBeInTheDocument(); + expect(screen.getByText('I am Link')).toBeInTheDocument(); }); }); diff --git a/plugins/catalog/src/components/EntityProcessingErrorsPanel/EntityProcessingErrorsPanel.test.tsx b/plugins/catalog/src/components/EntityProcessingErrorsPanel/EntityProcessingErrorsPanel.test.tsx index cfe3022261..350349fe95 100644 --- a/plugins/catalog/src/components/EntityProcessingErrorsPanel/EntityProcessingErrorsPanel.test.tsx +++ b/plugins/catalog/src/components/EntityProcessingErrorsPanel/EntityProcessingErrorsPanel.test.tsx @@ -226,7 +226,7 @@ describe('', () => { expect(screen.getByText('Error: Foo')).toBeInTheDocument(); expect(screen.queryByText('Error: This should not be rendered')).toBeNull(); expect( - screen.queryByText('The error below originates from'), + screen.getByText('The error below originates from'), ).toBeInTheDocument(); }); }); diff --git a/plugins/catalog/src/components/EntitySwitch/EntitySwitch.test.tsx b/plugins/catalog/src/components/EntitySwitch/EntitySwitch.test.tsx index d2c51465b5..164c7e60fd 100644 --- a/plugins/catalog/src/components/EntitySwitch/EntitySwitch.test.tsx +++ b/plugins/catalog/src/components/EntitySwitch/EntitySwitch.test.tsx @@ -54,7 +54,7 @@ describe('EntitySwitch', () => { , ); - expect(screen.queryByText('A')).toBeInTheDocument(); + expect(screen.getByText('A')).toBeInTheDocument(); expect(screen.queryByText('B')).not.toBeInTheDocument(); expect(screen.queryByText('C')).not.toBeInTheDocument(); @@ -69,7 +69,7 @@ describe('EntitySwitch', () => { ); expect(screen.queryByText('A')).not.toBeInTheDocument(); - expect(screen.queryByText('B')).toBeInTheDocument(); + expect(screen.getByText('B')).toBeInTheDocument(); expect(screen.queryByText('C')).not.toBeInTheDocument(); rendered.rerender( @@ -84,7 +84,7 @@ describe('EntitySwitch', () => { expect(screen.queryByText('A')).not.toBeInTheDocument(); expect(screen.queryByText('B')).not.toBeInTheDocument(); - expect(screen.queryByText('C')).toBeInTheDocument(); + expect(screen.getByText('C')).toBeInTheDocument(); rendered.rerender( @@ -96,7 +96,7 @@ describe('EntitySwitch', () => { expect(screen.queryByText('A')).not.toBeInTheDocument(); expect(screen.queryByText('B')).not.toBeInTheDocument(); - expect(screen.queryByText('C')).toBeInTheDocument(); + expect(screen.getByText('C')).toBeInTheDocument(); }); it('should switch child when filters switch', () => { @@ -113,7 +113,7 @@ describe('EntitySwitch', () => { , ); - expect(screen.queryByText('A')).toBeInTheDocument(); + expect(screen.getByText('A')).toBeInTheDocument(); expect(screen.queryByText('B')).not.toBeInTheDocument(); rendered.rerender( @@ -128,7 +128,7 @@ describe('EntitySwitch', () => { ); expect(screen.queryByText('A')).not.toBeInTheDocument(); - expect(screen.queryByText('B')).toBeInTheDocument(); + expect(screen.getByText('B')).toBeInTheDocument(); }); it('should switch with async condition that is true', async () => { diff --git a/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.test.tsx b/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.test.tsx index dc8d68e2b2..2fcd1c2702 100644 --- a/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.test.tsx +++ b/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.test.tsx @@ -67,8 +67,8 @@ describe('', () => { }, ); - expect(screen.queryByText(/System Diagram/)).toBeInTheDocument(); - expect(screen.queryByText(/namespace2\/system2/)).toBeInTheDocument(); + expect(screen.getByText(/System Diagram/)).toBeInTheDocument(); + expect(screen.getByText(/namespace2\/system2/)).toBeInTheDocument(); expect(screen.queryByText(/namespace\/entity/)).not.toBeInTheDocument(); }); diff --git a/plugins/cost-insights/src/components/BarChart/BarChart.test.tsx b/plugins/cost-insights/src/components/BarChart/BarChart.test.tsx index 530ca16e8f..37204d5ec6 100644 --- a/plugins/cost-insights/src/components/BarChart/BarChart.test.tsx +++ b/plugins/cost-insights/src/components/BarChart/BarChart.test.tsx @@ -104,7 +104,7 @@ describe('', () => { it('should display stepper if displaying more than 6 resources', async () => { const rendered = await renderWithProps({} as BarChartProps); - expect(rendered.queryByTestId('bar-chart-stepper')).toBeInTheDocument(); + expect(rendered.getByTestId('bar-chart-stepper')).toBeInTheDocument(); }); it('should display the next step button if resources are remaining', async () => { @@ -114,7 +114,7 @@ describe('', () => { rendered.queryByTestId('bar-chart-stepper-button-back'), ).not.toBeInTheDocument(); expect( - rendered.queryByTestId('bar-chart-stepper-button-next'), + rendered.getByTestId('bar-chart-stepper-button-next'), ).toBeInTheDocument(); }); diff --git a/plugins/cost-insights/src/components/BarChart/BarChartLegend.test.tsx b/plugins/cost-insights/src/components/BarChart/BarChartLegend.test.tsx index 690f0bbcd8..db515c233d 100644 --- a/plugins/cost-insights/src/components/BarChart/BarChartLegend.test.tsx +++ b/plugins/cost-insights/src/components/BarChart/BarChartLegend.test.tsx @@ -27,6 +27,6 @@ describe('', () => { , ); expect(rendered.getByText(/\$1,000/)).toBeInTheDocument(); - expect(rendered.queryByText(/\$5,000/)).toBeInTheDocument(); + expect(rendered.getByText(/\$5,000/)).toBeInTheDocument(); }); }); diff --git a/plugins/cost-insights/src/components/CostInsightsHeader/CostInsightsHeader.test.tsx b/plugins/cost-insights/src/components/CostInsightsHeader/CostInsightsHeader.test.tsx index 015a6279da..337d3d06b2 100644 --- a/plugins/cost-insights/src/components/CostInsightsHeader/CostInsightsHeader.test.tsx +++ b/plugins/cost-insights/src/components/CostInsightsHeader/CostInsightsHeader.test.tsx @@ -17,7 +17,6 @@ import { CostInsightsHeader } from './CostInsightsHeader'; import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils'; import React from 'react'; - import { ApiProvider } from '@backstage/core-app-api'; import { IdentityApi, identityApiRef } from '@backstage/core-plugin-api'; @@ -43,7 +42,7 @@ describe('', () => { , ); - expect(rendered.queryByText(/doing great/)).toBeInTheDocument(); + expect(rendered.getByText(/doing great/)).toBeInTheDocument(); }); it('Shows work to do when alerts > 1', async () => { @@ -57,7 +56,7 @@ describe('', () => { /> , ); - expect(rendered.queryByText(/few things/)).toBeInTheDocument(); + expect(rendered.getByText(/few things/)).toBeInTheDocument(); }); it('Handles grammar with a single alert', async () => { @@ -73,7 +72,7 @@ describe('', () => { ); expect(rendered.queryByText(/things/)).not.toBeInTheDocument(); - expect(rendered.queryByText(/one thing/)).toBeInTheDocument(); + expect(rendered.getByText(/one thing/)).toBeInTheDocument(); }); it('Shows no costs when hasCostData is false', async () => { @@ -87,7 +86,7 @@ describe('', () => { /> , ); - expect(rendered.queryByText(/this is awkward/)).toBeInTheDocument(); + expect(rendered.getByText(/this is awkward/)).toBeInTheDocument(); }); describe.each` @@ -109,9 +108,7 @@ describe('', () => { /> , ); - expect( - rendered.queryByText(/Test group display name/), - ).toBeInTheDocument(); + expect(rendered.getByText(/Test group display name/)).toBeInTheDocument(); }); it('Fallbacks to group id when display name not available', async () => { @@ -125,7 +122,7 @@ describe('', () => { /> , ); - expect(rendered.queryByText(/test-user-group-1/)).toBeInTheDocument(); + expect(rendered.getByText(/test-user-group-1/)).toBeInTheDocument(); }); }); }); diff --git a/plugins/cost-insights/src/components/PeriodSelect/PeriodSelect.test.tsx b/plugins/cost-insights/src/components/PeriodSelect/PeriodSelect.test.tsx index dfac13dd42..7cb95d8006 100644 --- a/plugins/cost-insights/src/components/PeriodSelect/PeriodSelect.test.tsx +++ b/plugins/cost-insights/src/components/PeriodSelect/PeriodSelect.test.tsx @@ -15,7 +15,7 @@ */ import React from 'react'; -import { getByRole, waitFor } from '@testing-library/react'; +import { getByRole, screen, waitFor } from '@testing-library/react'; import { renderInTestApp } from '@backstage/test-utils'; import userEvent from '@testing-library/user-event'; import { PeriodSelect, getDefaultOptions } from './PeriodSelect'; @@ -29,7 +29,7 @@ const options = getDefaultOptions(lastCompleteBillingDate); describe('', () => { it('Renders without exploding', async () => { - const rendered = await renderInTestApp( + await renderInTestApp( @@ -39,11 +39,11 @@ describe('', () => { /> , ); - expect(rendered.getByTestId('period-select')).toBeInTheDocument(); + expect(screen.getByTestId('period-select')).toBeInTheDocument(); }); it('Should display all costGrowth period options', async () => { - const rendered = await renderInTestApp( + await renderInTestApp( @@ -53,13 +53,13 @@ describe('', () => { /> , ); - const periodSelectContainer = rendered.getByTestId('period-select'); + const periodSelectContainer = screen.getByTestId('period-select'); const button = getByRole(periodSelectContainer, 'button'); await userEvent.click(button); - await waitFor(() => rendered.getByText('Past 60 Days')); + await waitFor(() => screen.getByText('Past 60 Days')); options.forEach(option => expect( - rendered.getByTestId(`period-select-option-${option.value}`), + screen.getByTestId(`period-select-option-${option.value}`), ).toBeInTheDocument(), ); }); @@ -78,19 +78,19 @@ describe('', () => { ? Duration.P30D : DefaultPageFilters.duration; - const rendered = await renderInTestApp( + await renderInTestApp( , , ); - const periodSelect = rendered.getByTestId('period-select'); + const periodSelect = screen.getByTestId('period-select'); const button = getByRole(periodSelect, 'button'); await userEvent.click(button); await userEvent.click( - rendered.getByTestId(`period-select-option-${duration}`), + screen.getByTestId(`period-select-option-${duration}`), ); expect(mockOnSelect).toHaveBeenLastCalledWith(duration); }); diff --git a/plugins/cost-insights/src/components/ProjectSelect/ProjectSelect.test.tsx b/plugins/cost-insights/src/components/ProjectSelect/ProjectSelect.test.tsx index 798b29de0d..7dd5b4253f 100644 --- a/plugins/cost-insights/src/components/ProjectSelect/ProjectSelect.test.tsx +++ b/plugins/cost-insights/src/components/ProjectSelect/ProjectSelect.test.tsx @@ -15,7 +15,7 @@ */ import React from 'react'; -import { getByRole, waitFor } from '@testing-library/react'; +import { getByRole, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { ProjectSelect } from './ProjectSelect'; import { MockFilterProvider } from '../../testUtils'; @@ -42,23 +42,19 @@ describe('', () => { }); it('Renders without exploding', async () => { - const rendered = await renderInTestApp(Component); - expect(rendered.getByText('All Projects')).toBeInTheDocument(); + await renderInTestApp(Component); + expect(screen.getByText('All Projects')).toBeInTheDocument(); }); it('shows all projects in the filter select', async () => { - const rendered = await renderInTestApp(Component); - const projectSelectContainer = rendered.getByTestId( - 'project-filter-select', - ); + await renderInTestApp(Component); + const projectSelectContainer = screen.getByTestId('project-filter-select'); const button = getByRole(projectSelectContainer, 'button'); await userEvent.click(button); - await waitFor(() => rendered.getByTestId('option-all')); + await waitFor(() => screen.getByTestId('option-all')); mockProjects.forEach(project => - expect( - rendered.getByText(project.name ?? project.id), - ).toBeInTheDocument(), + expect(screen.getByText(project.name ?? project.id)).toBeInTheDocument(), ); }); }); diff --git a/plugins/gcalendar/src/components/CalendarCard/AttendeeChip.test.tsx b/plugins/gcalendar/src/components/CalendarCard/AttendeeChip.test.tsx index 64485e74ab..769a225de3 100644 --- a/plugins/gcalendar/src/components/CalendarCard/AttendeeChip.test.tsx +++ b/plugins/gcalendar/src/components/CalendarCard/AttendeeChip.test.tsx @@ -13,10 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +import { screen } from '@testing-library/react'; import React from 'react'; - import { renderInTestApp } from '@backstage/test-utils'; - import { AttendeeChip } from './AttendeeChip'; import { EventAttendee, ResponseStatus } from '../../api'; @@ -27,8 +27,8 @@ describe('', () => { email, responseStatus: ResponseStatus.needsAction, }; - const { queryByText } = await renderInTestApp(); - expect(queryByText(email)).toBeInTheDocument(); + await renderInTestApp(); + expect(screen.getByText(email)).toBeInTheDocument(); }); it('renders accepted icon', async () => { @@ -37,8 +37,8 @@ describe('', () => { email, responseStatus: ResponseStatus.accepted, }; - const { getByTestId } = await renderInTestApp(); - expect(getByTestId('accepted-icon')).toBeInTheDocument(); + await renderInTestApp(); + expect(screen.getByTestId('accepted-icon')).toBeInTheDocument(); }); it('renders declined icon', async () => { @@ -47,7 +47,7 @@ describe('', () => { email, responseStatus: ResponseStatus.declined, }; - const { getByTestId } = await renderInTestApp(); - expect(getByTestId('declined-icon')).toBeInTheDocument(); + await renderInTestApp(); + expect(screen.getByTestId('declined-icon')).toBeInTheDocument(); }); }); diff --git a/plugins/gcalendar/src/components/CalendarCard/CalendarEvent.test.tsx b/plugins/gcalendar/src/components/CalendarCard/CalendarEvent.test.tsx index 7a48903bec..4a1ca884a9 100644 --- a/plugins/gcalendar/src/components/CalendarCard/CalendarEvent.test.tsx +++ b/plugins/gcalendar/src/components/CalendarCard/CalendarEvent.test.tsx @@ -13,11 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { fireEvent } from '@testing-library/react'; +import { screen } from '@testing-library/react'; import React from 'react'; - import { renderInTestApp } from '@backstage/test-utils'; - import { CalendarEvent } from './CalendarEvent'; describe('', () => { @@ -42,16 +42,14 @@ describe('', () => { }; it('should render calendar event', async () => { - const { queryByText, queryByTestId } = await renderInTestApp( - , - ); - expect(queryByText(event.summary)).toBeInTheDocument(); - expect(queryByTestId('calendar-event-zoom-link')).toBeInTheDocument(); - expect(queryByTestId('calendar-event-zoom-link')).toHaveAttribute( + await renderInTestApp(); + expect(screen.getByText(event.summary)).toBeInTheDocument(); + expect(screen.getByTestId('calendar-event-zoom-link')).toBeInTheDocument(); + expect(screen.queryByTestId('calendar-event-zoom-link')).toHaveAttribute( 'href', event.conferenceData.entryPoints[0].uri, ); - expect(queryByTestId('calendar-event-time')).toBeInTheDocument(); + expect(screen.getByTestId('calendar-event-time')).toBeInTheDocument(); }); it('should not render time for events longer than 1 day', async () => { @@ -64,20 +62,18 @@ describe('', () => { date: '2022-02-19', }, }; - const { queryByText, queryByTestId } = await renderInTestApp( - , - ); - expect(queryByText(allDayEvent.summary)).toBeInTheDocument(); - expect(queryByTestId('calendar-event-time')).not.toBeInTheDocument(); + await renderInTestApp(); + expect(screen.getByText(allDayEvent.summary)).toBeInTheDocument(); + expect(screen.queryByTestId('calendar-event-time')).not.toBeInTheDocument(); }); it('should show popover on click', async () => { - const { queryByTestId, getByTestId } = await renderInTestApp( - , - ); - expect(queryByTestId('calendar-event-popover')).not.toBeInTheDocument(); + await renderInTestApp(); + expect( + screen.queryByTestId('calendar-event-popover'), + ).not.toBeInTheDocument(); - fireEvent.click(getByTestId('calendar-event')); - expect(queryByTestId('calendar-event-popover')).toBeInTheDocument(); + fireEvent.click(screen.getByTestId('calendar-event')); + expect(screen.getByTestId('calendar-event-popover')).toBeInTheDocument(); }); }); diff --git a/plugins/gcalendar/src/components/CalendarCard/CalendarEventPopoverContent.test.tsx b/plugins/gcalendar/src/components/CalendarCard/CalendarEventPopoverContent.test.tsx index fe48b2fd5a..107a3ed180 100644 --- a/plugins/gcalendar/src/components/CalendarCard/CalendarEventPopoverContent.test.tsx +++ b/plugins/gcalendar/src/components/CalendarCard/CalendarEventPopoverContent.test.tsx @@ -13,10 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import React from 'react'; - +import { screen } from '@testing-library/react'; import { renderInTestApp } from '@backstage/test-utils'; - import { CalendarEventPopoverContent } from './CalendarEventPopoverContent'; describe('', () => { @@ -35,21 +35,18 @@ describe('', () => { }; it('should render event info', async () => { - const { queryByText, queryByTestId } = await renderInTestApp( - , - ); - expect(queryByText(event.summary)).toBeInTheDocument(); - expect(queryByText(event.description)).toBeInTheDocument(); - expect(queryByText(event.attendees[0].email)).toBeInTheDocument(); - expect(queryByText('Join Zoom Meeting')).toBeInTheDocument(); - expect(queryByText('Join Zoom Meeting')?.closest('a')).toHaveAttribute( - 'href', - event.conferenceData.entryPoints[0].uri, - ); - expect(queryByTestId('open-calendar-link')).toHaveAttribute( + await renderInTestApp(); + expect(screen.getByText(event.summary)).toBeInTheDocument(); + expect(screen.getByText(event.description)).toBeInTheDocument(); + expect(screen.getByText(event.attendees[0].email)).toBeInTheDocument(); + expect(screen.getByText('Join Zoom Meeting')).toBeInTheDocument(); + expect( + screen.queryByText('Join Zoom Meeting')?.closest('a'), + ).toHaveAttribute('href', event.conferenceData.entryPoints[0].uri); + expect(screen.queryByTestId('open-calendar-link')).toHaveAttribute( 'href', event.htmlLink, ); - expect(queryByText(event.attendees[0].email)).toBeInTheDocument(); + expect(screen.getByText(event.attendees[0].email)).toBeInTheDocument(); }); }); diff --git a/plugins/lighthouse/src/components/AuditList/AuditListTable.test.tsx b/plugins/lighthouse/src/components/AuditList/AuditListTable.test.tsx index d8a54928b2..c2ee202841 100644 --- a/plugins/lighthouse/src/components/AuditList/AuditListTable.test.tsx +++ b/plugins/lighthouse/src/components/AuditList/AuditListTable.test.tsx @@ -76,7 +76,7 @@ describe('AuditListTable', () => { if (!website) throw new Error('https://anchor.fm must be present in fixture'); expect( - rendered.queryByText(formatTime(website.lastAudit.timeCreated)), + rendered.getByText(formatTime(website.lastAudit.timeCreated)), ).toBeInTheDocument(); }); diff --git a/plugins/lighthouse/src/components/AuditView/index.test.tsx b/plugins/lighthouse/src/components/AuditView/index.test.tsx index 00b2843a50..c68daddc67 100644 --- a/plugins/lighthouse/src/components/AuditView/index.test.tsx +++ b/plugins/lighthouse/src/components/AuditView/index.test.tsx @@ -98,7 +98,7 @@ describe('AuditView', () => { websiteResponse.audits.forEach(a => { expect( - rendered.queryByText(formatTime(a.timeCreated)), + rendered.getByText(formatTime(a.timeCreated)), ).toBeInTheDocument(); }); }); @@ -199,7 +199,7 @@ describe('AuditView', () => { await rendered.findByTestId('audit-sidebar'); - expect(rendered.queryByTestId('progress')).toBeInTheDocument(); + expect(rendered.getByTestId('progress')).toBeInTheDocument(); }); }); @@ -219,7 +219,7 @@ describe('AuditView', () => { await rendered.findByTestId('audit-sidebar'); - expect(rendered.queryByText(/This audit failed/)).toBeInTheDocument(); + expect(rendered.getByText(/This audit failed/)).toBeInTheDocument(); }); }); }); diff --git a/plugins/lighthouse/src/components/Intro/index.test.tsx b/plugins/lighthouse/src/components/Intro/index.test.tsx index ed4a11ff43..173dce1315 100644 --- a/plugins/lighthouse/src/components/Intro/index.test.tsx +++ b/plugins/lighthouse/src/components/Intro/index.test.tsx @@ -25,7 +25,7 @@ describe('LighthouseIntro', () => { it('renders successfully', () => { const rendered = render(wrapInTestApp()); expect( - rendered.queryByText('Welcome to Lighthouse in Backstage!'), + rendered.getByText('Welcome to Lighthouse in Backstage!'), ).toBeInTheDocument(); }); @@ -35,7 +35,7 @@ describe('LighthouseIntro', () => { it('selects the first text element', () => { const rendered = render(wrapInTestApp()); - expect(rendered.queryByText(firstTabRe)).toBeInTheDocument(); + expect(rendered.getByText(firstTabRe)).toBeInTheDocument(); expect(rendered.queryByText(secondTabRe)).not.toBeInTheDocument(); }); @@ -43,7 +43,7 @@ describe('LighthouseIntro', () => { const rendered = render(wrapInTestApp()); fireEvent.click(rendered.getByText('Setup')); expect(rendered.queryByText(firstTabRe)).not.toBeInTheDocument(); - expect(rendered.queryByText(secondTabRe)).toBeInTheDocument(); + expect(rendered.getByText(secondTabRe)).toBeInTheDocument(); }); }); diff --git a/plugins/pagerduty/src/components/Incident/Incidents.test.tsx b/plugins/pagerduty/src/components/Incident/Incidents.test.tsx index a83874a995..bd2016eb16 100644 --- a/plugins/pagerduty/src/components/Incident/Incidents.test.tsx +++ b/plugins/pagerduty/src/components/Incident/Incidents.test.tsx @@ -13,8 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import React from 'react'; -import { render, waitFor } from '@testing-library/react'; +import { render, screen, waitFor } from '@testing-library/react'; import { Incidents } from './Incidents'; import { TestApiRegistry, wrapInTestApp } from '@backstage/test-utils'; import { pagerDutyApiRef } from '../../api'; @@ -32,15 +33,15 @@ describe('Incidents', () => { .fn() .mockImplementationOnce(async () => ({ incidents: [] })); - const { getByText, queryByTestId } = render( + render( wrapInTestApp( , ), ); - await waitFor(() => !queryByTestId('progress')); - expect(getByText('Nice! No incidents found!')).toBeInTheDocument(); + await waitFor(() => !screen.queryByTestId('progress')); + expect(screen.getByText('Nice! No incidents found!')).toBeInTheDocument(); }); it('Renders all incidents', async () => { @@ -85,25 +86,25 @@ describe('Incidents', () => { }, ] as PagerDutyIncident[], })); - const { getByText, getAllByTitle, queryByTestId } = render( + render( wrapInTestApp( , ), ); - await waitFor(() => !queryByTestId('progress')); - expect(getByText('title1')).toBeInTheDocument(); - expect(getByText('title2')).toBeInTheDocument(); - expect(getByText('person1')).toBeInTheDocument(); - expect(getByText('person2')).toBeInTheDocument(); - expect(getByText('triggered')).toBeInTheDocument(); - expect(getByText('acknowledged')).toBeInTheDocument(); - expect(queryByTestId('chip-triggered')).toBeInTheDocument(); - expect(queryByTestId('chip-acknowledged')).toBeInTheDocument(); + await waitFor(() => !screen.queryByTestId('progress')); + expect(screen.getByText('title1')).toBeInTheDocument(); + expect(screen.getByText('title2')).toBeInTheDocument(); + expect(screen.getByText('person1')).toBeInTheDocument(); + expect(screen.getByText('person2')).toBeInTheDocument(); + expect(screen.getByText('triggered')).toBeInTheDocument(); + expect(screen.getByText('acknowledged')).toBeInTheDocument(); + expect(screen.getByTestId('chip-triggered')).toBeInTheDocument(); + expect(screen.getByTestId('chip-acknowledged')).toBeInTheDocument(); // assert links, mailto and hrefs, date calculation - expect(getAllByTitle('View in PagerDuty').length).toEqual(2); + expect(screen.getAllByTitle('View in PagerDuty').length).toEqual(2); }); it('Handle errors', async () => { @@ -111,16 +112,18 @@ describe('Incidents', () => { .fn() .mockRejectedValueOnce(new Error('Error occurred')); - const { getByText, queryByTestId } = render( + render( wrapInTestApp( , ), ); - await waitFor(() => !queryByTestId('progress')); + await waitFor(() => !screen.queryByTestId('progress')); expect( - getByText('Error encountered while fetching information. Error occurred'), + screen.getByText( + 'Error encountered while fetching information. Error occurred', + ), ).toBeInTheDocument(); }); }); diff --git a/plugins/playlist/src/components/CreatePlaylistButton/CreatePlaylistButton.test.tsx b/plugins/playlist/src/components/CreatePlaylistButton/CreatePlaylistButton.test.tsx index e00f7dc582..ef8ca57b69 100644 --- a/plugins/playlist/src/components/CreatePlaylistButton/CreatePlaylistButton.test.tsx +++ b/plugins/playlist/src/components/CreatePlaylistButton/CreatePlaylistButton.test.tsx @@ -26,7 +26,6 @@ import { fireEvent, waitFor } from '@testing-library/react'; import { act } from '@testing-library/react-hooks'; import React from 'react'; import { SWRConfig } from 'swr'; - import { PlaylistApi, playlistApiRef } from '../../api'; import { rootRouteRef } from '../../routes'; import { CreatePlaylistButton } from './CreatePlaylistButton'; @@ -103,7 +102,7 @@ describe('', () => { fireEvent.click(rendered.getByRole('button')); }); expect( - rendered.queryByTestId('mock-playlist-edit-dialog'), + rendered.getByTestId('mock-playlist-edit-dialog'), ).toBeInTheDocument(); }); diff --git a/plugins/playlist/src/components/EntityPlaylistDialog/EntityPlaylistDialog.test.tsx b/plugins/playlist/src/components/EntityPlaylistDialog/EntityPlaylistDialog.test.tsx index 9c61105ef9..1d9b298e19 100644 --- a/plugins/playlist/src/components/EntityPlaylistDialog/EntityPlaylistDialog.test.tsx +++ b/plugins/playlist/src/components/EntityPlaylistDialog/EntityPlaylistDialog.test.tsx @@ -28,7 +28,6 @@ import { fireEvent, getByRole, waitFor } from '@testing-library/react'; import { act } from '@testing-library/react-hooks'; import React from 'react'; import { SWRConfig } from 'swr'; - import { PlaylistApi, playlistApiRef } from '../../api'; import { rootRouteRef } from '../../routes'; import { EntityPlaylistDialog } from './EntityPlaylistDialog'; @@ -182,7 +181,7 @@ describe('EntityPlaylistDialog', () => { }); expect( - rendered.queryByTestId('mock-playlist-edit-dialog'), + rendered.getByTestId('mock-playlist-edit-dialog'), ).toBeInTheDocument(); act(() => { diff --git a/plugins/playlist/src/components/PersonalListPicker/PersonalListPicker.test.tsx b/plugins/playlist/src/components/PersonalListPicker/PersonalListPicker.test.tsx index 9255ee1bdb..b8ef0d9de0 100644 --- a/plugins/playlist/src/components/PersonalListPicker/PersonalListPicker.test.tsx +++ b/plugins/playlist/src/components/PersonalListPicker/PersonalListPicker.test.tsx @@ -24,7 +24,7 @@ import { } from '@backstage/core-plugin-api'; import { Playlist } from '@backstage/plugin-playlist-common'; import { MockStorageApi, TestApiRegistry } from '@backstage/test-utils'; -import { fireEvent, render, waitFor } from '@testing-library/react'; +import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import React from 'react'; import { MockPlaylistListProvider } from '../../testUtils'; @@ -94,7 +94,7 @@ describe('', () => { }); it('renders filter groups', async () => { - const { queryByText } = render( + render( @@ -103,8 +103,8 @@ describe('', () => { ); await waitFor(() => { - expect(queryByText('Personal')).toBeInTheDocument(); - expect(queryByText('Test Company')).toBeInTheDocument(); + expect(screen.getByText('Personal')).toBeInTheDocument(); + expect(screen.getByText('Test Company')).toBeInTheDocument(); }); }); diff --git a/plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.test.tsx b/plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.test.tsx index f7720b25c1..21658ef36e 100644 --- a/plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.test.tsx +++ b/plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.test.tsx @@ -27,7 +27,6 @@ import { fireEvent, waitFor } from '@testing-library/react'; import { act } from '@testing-library/react-hooks'; import React from 'react'; import { SWRConfig } from 'swr'; - import { PlaylistApi, playlistApiRef } from '../../api'; import { PlaylistEntitiesTable } from './PlaylistEntitiesTable'; @@ -158,7 +157,7 @@ describe('PlaylistEntitiesTable', () => { }); expect( - rendered.queryByTestId('mock-add-entities-drawer'), + rendered.getByTestId('mock-add-entities-drawer'), ).toBeInTheDocument(); act(() => { diff --git a/plugins/playlist/src/components/PlaylistPage/PlaylistHeader.test.tsx b/plugins/playlist/src/components/PlaylistPage/PlaylistHeader.test.tsx index 39b051140e..4594a43a88 100644 --- a/plugins/playlist/src/components/PlaylistPage/PlaylistHeader.test.tsx +++ b/plugins/playlist/src/components/PlaylistPage/PlaylistHeader.test.tsx @@ -31,7 +31,6 @@ import { fireEvent, waitFor } from '@testing-library/react'; import { act } from '@testing-library/react-hooks'; import React from 'react'; import { SWRConfig } from 'swr'; - import { PlaylistApi, playlistApiRef } from '../../api'; import { rootRouteRef } from '../../routes'; import { PlaylistHeader } from './PlaylistHeader'; @@ -122,7 +121,7 @@ describe('PlaylistHeader', () => { testPlaylist.public = false; rendered.rerender(element); - expect(rendered.queryByText('private')).toBeInTheDocument(); + expect(rendered.getByText('private')).toBeInTheDocument(); }); it('has edit and delete options enabled if authorized', async () => { @@ -202,7 +201,7 @@ describe('PlaylistHeader', () => { }); expect( - rendered.queryByTestId('mock-playlist-edit-dialog'), + rendered.getByTestId('mock-playlist-edit-dialog'), ).toBeInTheDocument(); act(() => { diff --git a/plugins/scaffolder/src/components/ActionsPage/ActionsPage.test.tsx b/plugins/scaffolder/src/components/ActionsPage/ActionsPage.test.tsx index 40683f01ba..8e2184edf1 100644 --- a/plugins/scaffolder/src/components/ActionsPage/ActionsPage.test.tsx +++ b/plugins/scaffolder/src/components/ActionsPage/ActionsPage.test.tsx @@ -65,9 +65,9 @@ describe('TemplatePage', () => { }, }, ); - expect(rendered.queryByText('Test title')).toBeInTheDocument(); - expect(rendered.queryByText('example description')).toBeInTheDocument(); - expect(rendered.queryByText('foobar')).toBeInTheDocument(); + expect(rendered.getByText('Test title')).toBeInTheDocument(); + expect(rendered.getByText('example description')).toBeInTheDocument(); + expect(rendered.getByText('foobar')).toBeInTheDocument(); expect(rendered.queryByText('output')).not.toBeInTheDocument(); }); @@ -109,10 +109,10 @@ describe('TemplatePage', () => { }, }, ); - expect(rendered.queryByText('Test title')).toBeInTheDocument(); - expect(rendered.queryByText('example description')).toBeInTheDocument(); - expect(rendered.queryByText('foobar')).toBeInTheDocument(); - expect(rendered.queryByText('Test output')).toBeInTheDocument(); + expect(rendered.getByText('Test title')).toBeInTheDocument(); + expect(rendered.getByText('example description')).toBeInTheDocument(); + expect(rendered.getByText('foobar')).toBeInTheDocument(); + expect(rendered.getByText('Test output')).toBeInTheDocument(); }); it('renders action with oneOf input', async () => { @@ -160,10 +160,10 @@ describe('TemplatePage', () => { }, }, ); - expect(rendered.queryByText('oneOf')).toBeInTheDocument(); - expect(rendered.queryByText('Foo title')).toBeInTheDocument(); - expect(rendered.queryByText('Foo description')).toBeInTheDocument(); - expect(rendered.queryByText('Bar title')).toBeInTheDocument(); - expect(rendered.queryByText('Bar description')).toBeInTheDocument(); + expect(rendered.getByText('oneOf')).toBeInTheDocument(); + expect(rendered.getByText('Foo title')).toBeInTheDocument(); + expect(rendered.getByText('Foo description')).toBeInTheDocument(); + expect(rendered.getByText('Bar title')).toBeInTheDocument(); + expect(rendered.getByText('Bar description')).toBeInTheDocument(); }); }); diff --git a/plugins/scaffolder/src/components/ScaffolderPage/ScaffolderPageContextMenu.test.tsx b/plugins/scaffolder/src/components/ScaffolderPage/ScaffolderPageContextMenu.test.tsx index 2d07416025..02869bb6da 100644 --- a/plugins/scaffolder/src/components/ScaffolderPage/ScaffolderPageContextMenu.test.tsx +++ b/plugins/scaffolder/src/components/ScaffolderPage/ScaffolderPageContextMenu.test.tsx @@ -45,7 +45,7 @@ describe('ScaffolderPageContextMenu', () => { await userEvent.click(screen.getByTestId('container').firstElementChild!); - expect(screen.queryByText('Template Editor')).toBeInTheDocument(); + expect(screen.getByText('Template Editor')).toBeInTheDocument(); expect(screen.queryByText('Installed Actions')).not.toBeInTheDocument(); }); @@ -62,7 +62,7 @@ describe('ScaffolderPageContextMenu', () => { await userEvent.click(screen.getByTestId('container').firstElementChild!); expect(screen.queryByText('Template Editor')).not.toBeInTheDocument(); - expect(screen.queryByText('Installed Actions')).toBeInTheDocument(); + expect(screen.getByText('Installed Actions')).toBeInTheDocument(); }); it('renders all options', async () => { @@ -77,7 +77,7 @@ describe('ScaffolderPageContextMenu', () => { await userEvent.click(screen.getByTestId('container').firstElementChild!); - expect(screen.queryByText('Template Editor')).toBeInTheDocument(); - expect(screen.queryByText('Installed Actions')).toBeInTheDocument(); + expect(screen.getByText('Template Editor')).toBeInTheDocument(); + expect(screen.getByText('Installed Actions')).toBeInTheDocument(); }); }); diff --git a/plugins/scaffolder/src/components/TaskPage/IconLink.test.tsx b/plugins/scaffolder/src/components/TaskPage/IconLink.test.tsx index 9c1b021071..f7ce850cd8 100644 --- a/plugins/scaffolder/src/components/TaskPage/IconLink.test.tsx +++ b/plugins/scaffolder/src/components/TaskPage/IconLink.test.tsx @@ -33,6 +33,6 @@ describe('IconLink', () => { , ); - expect(rendered.queryByText('I am Link')).toBeInTheDocument(); + expect(rendered.getByText('I am Link')).toBeInTheDocument(); }); }); diff --git a/plugins/scaffolder/src/components/TemplateEditorPage/DryRunResults/DryRunResultsList.test.tsx b/plugins/scaffolder/src/components/TemplateEditorPage/DryRunResults/DryRunResultsList.test.tsx index 65eb59c84a..417c23c483 100644 --- a/plugins/scaffolder/src/components/TemplateEditorPage/DryRunResults/DryRunResultsList.test.tsx +++ b/plugins/scaffolder/src/components/TemplateEditorPage/DryRunResults/DryRunResultsList.test.tsx @@ -70,7 +70,7 @@ describe('DryRunResultsList', () => { , ); - expect(screen.queryByText('Result 1')).toBeInTheDocument(); + expect(screen.getByText('Result 1')).toBeInTheDocument(); expect(screen.queryByText('Result 2')).not.toBeInTheDocument(); await act(async () => { @@ -84,12 +84,12 @@ describe('DryRunResultsList', () => { ); }); - expect(screen.queryByText('Result 1')).toBeInTheDocument(); - expect(screen.queryByText('Result 2')).toBeInTheDocument(); + expect(screen.getByText('Result 1')).toBeInTheDocument(); + expect(screen.getByText('Result 2')).toBeInTheDocument(); await userEvent.click(screen.getAllByLabelText('delete')[0]); expect(screen.queryByText('Result 1')).not.toBeInTheDocument(); - expect(screen.queryByText('Result 2')).toBeInTheDocument(); + expect(screen.getByText('Result 2')).toBeInTheDocument(); }); }); diff --git a/plugins/scaffolder/src/components/TemplatePage/TemplatePage.test.tsx b/plugins/scaffolder/src/components/TemplatePage/TemplatePage.test.tsx index 71f5ffad47..5b16c21364 100644 --- a/plugins/scaffolder/src/components/TemplatePage/TemplatePage.test.tsx +++ b/plugins/scaffolder/src/components/TemplatePage/TemplatePage.test.tsx @@ -19,7 +19,7 @@ import { renderInTestApp, TestApiRegistry, } from '@backstage/test-utils'; -import { act, fireEvent, within } from '@testing-library/react'; +import { act, fireEvent, screen, within } from '@testing-library/react'; import React from 'react'; import { Route, Routes } from 'react-router'; import { scaffolderApiRef } from '../../api'; @@ -31,7 +31,6 @@ import { FeatureFlagsApi, analyticsApiRef, } from '@backstage/core-plugin-api'; - import { ApiProvider } from '@backstage/core-app-api'; import { errorApiRef } from '@backstage/core-plugin-api'; @@ -135,8 +134,8 @@ describe('TemplatePage', () => { }, ); - expect(rendered.queryByText('Create a New Component')).toBeInTheDocument(); - expect(rendered.queryByText('React SSR Template')).toBeInTheDocument(); + expect(rendered.getByText('Create a New Component')).toBeInTheDocument(); + expect(rendered.getByText('React SSR Template')).toBeInTheDocument(); }); it('renders spinner while loading', async () => { @@ -156,8 +155,8 @@ describe('TemplatePage', () => { }, ); - expect(rendered.queryByText('Create a New Component')).toBeInTheDocument(); - expect(rendered.queryByTestId('loading-progress')).toBeInTheDocument(); + expect(rendered.getByText('Create a New Component')).toBeInTheDocument(); + expect(rendered.getByTestId('loading-progress')).toBeInTheDocument(); await act(async () => { resolve!({ @@ -248,7 +247,7 @@ describe('TemplatePage', () => { expect( rendered.queryByText('Create a New Component'), ).not.toBeInTheDocument(); - expect(rendered.queryByText('This is root')).toBeInTheDocument(); + expect(rendered.getByText('This is root')).toBeInTheDocument(); }); it('display template with oneOf', async () => { @@ -330,7 +329,7 @@ describe('TemplatePage', () => { schemaMockValue, ); - const { queryByText } = await renderInTestApp( + await renderInTestApp( , @@ -341,9 +340,9 @@ describe('TemplatePage', () => { }, ); - expect(queryByText('Name')).not.toBeInTheDocument(); - expect(queryByText('Description')).toBeInTheDocument(); - expect(queryByText('Owner')).toBeInTheDocument(); - expect(queryByText('Send data')).toBeInTheDocument(); + expect(screen.queryByText('Name')).not.toBeInTheDocument(); + expect(screen.getByText('Description')).toBeInTheDocument(); + expect(screen.getByText('Owner')).toBeInTheDocument(); + expect(screen.getByText('Send data')).toBeInTheDocument(); }); }); diff --git a/plugins/scaffolder/src/next/TemplateListPage/RegisterExistingButton.test.tsx b/plugins/scaffolder/src/next/TemplateListPage/RegisterExistingButton.test.tsx index a8e377bd3d..3c2807c4c8 100644 --- a/plugins/scaffolder/src/next/TemplateListPage/RegisterExistingButton.test.tsx +++ b/plugins/scaffolder/src/next/TemplateListPage/RegisterExistingButton.test.tsx @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +import { screen } from '@testing-library/react'; import { renderInTestApp } from '@backstage/test-utils'; import React from 'react'; import { RegisterExistingButton } from './RegisterExistingButton'; @@ -30,28 +32,22 @@ describe('RegisterExistingButton', () => { it('should not render if to is unset', async () => { (usePermission as jest.Mock).mockReturnValue({ allowed: true }); - const { queryByText } = await renderInTestApp( - , - ); + await renderInTestApp(); - expect(queryByText('Pick me')).not.toBeInTheDocument(); + expect(screen.queryByText('Pick me')).not.toBeInTheDocument(); }); it('should not render if permissions are not allowed', async () => { (usePermission as jest.Mock).mockReturnValue({ allowed: false }); - const { queryByText } = await renderInTestApp( - , - ); + await renderInTestApp(); - expect(queryByText('Pick me')).not.toBeInTheDocument(); + expect(screen.queryByText('Pick me')).not.toBeInTheDocument(); }); it('should render the button with the text', async () => { (usePermission as jest.Mock).mockReturnValue({ allowed: true }); - const { queryByText } = await renderInTestApp( - , - ); + await renderInTestApp(); - expect(queryByText('Pick me')).toBeInTheDocument(); + expect(screen.getByText('Pick me')).toBeInTheDocument(); }); }); diff --git a/plugins/techdocs/src/home/components/Grids/EntityListDocsGrid.test.tsx b/plugins/techdocs/src/home/components/Grids/EntityListDocsGrid.test.tsx index 2837ab340a..acaf01b318 100644 --- a/plugins/techdocs/src/home/components/Grids/EntityListDocsGrid.test.tsx +++ b/plugins/techdocs/src/home/components/Grids/EntityListDocsGrid.test.tsx @@ -103,9 +103,9 @@ describe('Entity List Docs Grid', () => { }, ); - expect(screen.queryByText('All Documentation')).toBeInTheDocument(); - expect(screen.queryByText('Documentation #1')).toBeInTheDocument(); - expect(screen.queryByText('Documentation #2')).toBeInTheDocument(); + expect(screen.getByText('All Documentation')).toBeInTheDocument(); + expect(screen.getByText('Documentation #1')).toBeInTheDocument(); + expect(screen.getByText('Documentation #2')).toBeInTheDocument(); expect(screen.queryByTestId('doc-not-found')).not.toBeInTheDocument(); }); @@ -131,8 +131,8 @@ describe('Entity List Docs Grid', () => { }, ); - expect(screen.queryByText('Curated Documentation')).toBeInTheDocument(); - expect(screen.queryByText('Documentation #1')).toBeInTheDocument(); + expect(screen.getByText('Curated Documentation')).toBeInTheDocument(); + expect(screen.getByText('Documentation #1')).toBeInTheDocument(); expect(screen.queryByText('Documentation #2')).not.toBeInTheDocument(); expect(screen.queryByTestId('doc-not-found')).not.toBeInTheDocument(); }); @@ -182,6 +182,6 @@ describe('Entity List Docs Grid', () => { expect(screen.queryByText('All Documentation')).not.toBeInTheDocument(); expect(screen.queryByText('Documentation #1')).not.toBeInTheDocument(); expect(screen.queryByText('Documentation #2')).not.toBeInTheDocument(); - expect(screen.queryByTestId('doc-not-found')).toBeInTheDocument(); + expect(screen.getByTestId('doc-not-found')).toBeInTheDocument(); }); }); From 76eb3e004d767822fe3b3c04d5a688d2d11fbf8e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 23 Nov 2022 10:12:04 +0000 Subject: [PATCH 73/83] Update dependency @apidevtools/json-schema-ref-parser to v9.0.9 Signed-off-by: Renovate Bot --- yarn.lock | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/yarn.lock b/yarn.lock index b542fe9694..ad73954b5d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -22,13 +22,14 @@ __metadata: linkType: hard "@apidevtools/json-schema-ref-parser@npm:^9.0.6": - version: 9.0.6 - resolution: "@apidevtools/json-schema-ref-parser@npm:9.0.6" + version: 9.0.9 + resolution: "@apidevtools/json-schema-ref-parser@npm:9.0.9" dependencies: "@jsdevtools/ono": ^7.1.3 + "@types/json-schema": ^7.0.6 call-me-maybe: ^1.0.1 - js-yaml: ^3.13.1 - checksum: c7ff53623ab8a9dd221772a5757fa0b9e5167a5ac3a71c23596634bae6efc85d8efcdebbe17f73ee5c027ea5afc48c705e8a720f02c4909f9a357d8027040b7b + js-yaml: ^4.1.0 + checksum: b21f6bdd37d2942c3967ee77569bc74fadd1b922f688daf5ef85057789a2c3a7f4afc473aa2f3a93ec950dabb6ef365f8bd9cf51e4e062a1ee1e59b989f8f9b4 languageName: node linkType: hard From 7079ab1c3faa94863295bcb198977cff4fd9f2b0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 23 Nov 2022 11:13:46 +0000 Subject: [PATCH 74/83] Update dependency prettier to v2.8.0 Signed-off-by: Renovate Bot --- microsite/yarn.lock | 6 +++--- yarn.lock | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/microsite/yarn.lock b/microsite/yarn.lock index 1fa6e492cb..f0e6bd698a 100644 --- a/microsite/yarn.lock +++ b/microsite/yarn.lock @@ -7393,11 +7393,11 @@ __metadata: linkType: hard "prettier@npm:^2.6.2": - version: 2.7.1 - resolution: "prettier@npm:2.7.1" + version: 2.8.0 + resolution: "prettier@npm:2.8.0" bin: prettier: bin-prettier.js - checksum: 55a4409182260866ab31284d929b3cb961e5fdb91fe0d2e099dac92eaecec890f36e524b4c19e6ceae839c99c6d7195817579cdffc8e2c80da0cb794463a748b + checksum: 72004ce0cc9bb097daf3e3833f62495768724392c1d5b178dd47372337616e9e50ecbb0804f236596223f7b5eb1bbe69cefc8957dca21112c5777e77ef73a564 languageName: node linkType: hard diff --git a/yarn.lock b/yarn.lock index 9d9354b8e1..dbd5a8d446 100644 --- a/yarn.lock +++ b/yarn.lock @@ -31163,11 +31163,11 @@ __metadata: linkType: hard "prettier@npm:^2.2.1, prettier@npm:^2.7.1": - version: 2.7.1 - resolution: "prettier@npm:2.7.1" + version: 2.8.0 + resolution: "prettier@npm:2.8.0" bin: prettier: bin-prettier.js - checksum: 55a4409182260866ab31284d929b3cb961e5fdb91fe0d2e099dac92eaecec890f36e524b4c19e6ceae839c99c6d7195817579cdffc8e2c80da0cb794463a748b + checksum: 72004ce0cc9bb097daf3e3833f62495768724392c1d5b178dd47372337616e9e50ecbb0804f236596223f7b5eb1bbe69cefc8957dca21112c5777e77ef73a564 languageName: node linkType: hard From 7d20fc9cbc1a471ae13fad9b966dcdc2f9fa3ab8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 23 Nov 2022 11:15:00 +0000 Subject: [PATCH 75/83] Update dependency webpack-dev-server to v4.11.1 Signed-off-by: Renovate Bot --- yarn.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/yarn.lock b/yarn.lock index 9d9354b8e1..bbc526dd57 100644 --- a/yarn.lock +++ b/yarn.lock @@ -33611,7 +33611,7 @@ __metadata: languageName: node linkType: hard -"selfsigned@npm:^2.0.0, selfsigned@npm:^2.0.1": +"selfsigned@npm:^2.0.0, selfsigned@npm:^2.1.1": version: 2.1.1 resolution: "selfsigned@npm:2.1.1" dependencies: @@ -37187,8 +37187,8 @@ __metadata: linkType: hard "webpack-dev-server@npm:^4.7.3": - version: 4.10.1 - resolution: "webpack-dev-server@npm:4.10.1" + version: 4.11.1 + resolution: "webpack-dev-server@npm:4.11.1" dependencies: "@types/bonjour": ^3.5.9 "@types/connect-history-api-fallback": ^1.3.5 @@ -37213,7 +37213,7 @@ __metadata: p-retry: ^4.5.0 rimraf: ^3.0.2 schema-utils: ^4.0.0 - selfsigned: ^2.0.1 + selfsigned: ^2.1.1 serve-index: ^1.9.1 sockjs: ^0.3.24 spdy: ^4.0.2 @@ -37226,7 +37226,7 @@ __metadata: optional: true bin: webpack-dev-server: bin/webpack-dev-server.js - checksum: d026e6be63058ba5f881c58c9d49367a26c43d76bb7c2a1d9fb80eeae644099cc098913b4e9f32e2ed89eff0e7cc08e03cae8a1c4e7a1c8f67c5c673ab70761e + checksum: b7601a39ee0f413988259e29a36835b0a68522cfaa161de5b7ec99b3399acdd99d44189add4aaf4a5191258bb130f9cf3e68919324a1955c7557f5fe6ab0d96c languageName: node linkType: hard From 2f6c7d485ea03a41234a781afe1abac748196217 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 23 Nov 2022 12:55:55 +0000 Subject: [PATCH 76/83] Update dependency yeoman-environment to v3.12.1 Signed-off-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index bbc526dd57..53a18f77bb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -37971,8 +37971,8 @@ __metadata: linkType: hard "yeoman-environment@npm:^3.9.1": - version: 3.10.0 - resolution: "yeoman-environment@npm:3.10.0" + version: 3.12.1 + resolution: "yeoman-environment@npm:3.12.1" dependencies: "@npmcli/arborist": ^4.0.4 are-we-there-yet: ^2.0.0 @@ -38015,7 +38015,7 @@ __metadata: mem-fs-editor: ^8.1.2 || ^9.0.0 bin: yoe: cli/index.js - checksum: 2ab844358d148889285fc9cd68b9eb6660af4721033c86f833ad60a0028bbe8b5c637fa290a1c29f54c4957df53e6c5cd05692c6e25e7d88c9442c9a5f9775dc + checksum: 71e777fcfa4baf26f9848265292447d7283f4bcb0e6b781018c8f8610c47c430e5a331eb0da03491621a7bcdd6ed40a2854c664a4f9f1ceb9ee111def37f52d1 languageName: node linkType: hard From eb1934270c2e59234f78b9540fbb4edd29ca367c Mon Sep 17 00:00:00 2001 From: Kurt King Date: Wed, 23 Nov 2022 07:33:01 -0600 Subject: [PATCH 77/83] update link to code of conduct Signed-off-by: Kurt King --- .github/ISSUE_TEMPLATE/feature.yaml | 2 +- .github/ISSUE_TEMPLATE/plugin.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/feature.yaml b/.github/ISSUE_TEMPLATE/feature.yaml index 9cac5055f1..b5e06d48cf 100644 --- a/.github/ISSUE_TEMPLATE/feature.yaml +++ b/.github/ISSUE_TEMPLATE/feature.yaml @@ -41,7 +41,7 @@ body: attributes: label: '🏢 Have you read the Code of Conduct?' options: - - label: 'I have read the [Contributing Guidelines](https://github.com/backstage/backstage/blob/master/CODE_OF_CONDUCT.md)' + - label: 'I have read the [Code of Conduct](https://github.com/backstage/backstage/blob/master/CODE_OF_CONDUCT.md)' required: true - type: dropdown id: willing-to-submit-pr diff --git a/.github/ISSUE_TEMPLATE/plugin.yaml b/.github/ISSUE_TEMPLATE/plugin.yaml index 9f3a708b41..a36c427981 100644 --- a/.github/ISSUE_TEMPLATE/plugin.yaml +++ b/.github/ISSUE_TEMPLATE/plugin.yaml @@ -39,7 +39,7 @@ body: attributes: label: '🏢 Have you read the Code of Conduct?' options: - - label: 'I have read the [Contributing Guidelines](https://github.com/backstage/backstage/blob/master/CODE_OF_CONDUCT.md)' + - label: 'I have read the [Code of Conduct](https://github.com/backstage/backstage/blob/master/CODE_OF_CONDUCT.md)' required: true - type: dropdown id: willing-to-submit-pr From 7a2e13b862b15627974e40edc2af340d388d1d34 Mon Sep 17 00:00:00 2001 From: Morgan Date: Wed, 23 Nov 2022 15:38:05 +0100 Subject: [PATCH 78/83] bump @azure/identiy to support node 18 Signed-off-by: Morgan --- plugins/techdocs-node/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/techdocs-node/package.json b/plugins/techdocs-node/package.json index 6c52c31110..ef900f49f9 100644 --- a/plugins/techdocs-node/package.json +++ b/plugins/techdocs-node/package.json @@ -39,7 +39,7 @@ "url": "https://github.com/backstage/backstage/issues" }, "dependencies": { - "@azure/identity": "^2.0.1", + "@azure/identity": "^2.1.0", "@azure/storage-blob": "^12.5.0", "@backstage/backend-common": "workspace:^", "@backstage/catalog-model": "workspace:^", From f63ac91186ac62039710a2ad67a4eacc0ca437ea Mon Sep 17 00:00:00 2001 From: Morgan Date: Wed, 23 Nov 2022 15:44:52 +0100 Subject: [PATCH 79/83] update lockfile Signed-off-by: Morgan --- yarn.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yarn.lock b/yarn.lock index 53a18f77bb..0c5fc3fd67 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1290,7 +1290,7 @@ __metadata: languageName: node linkType: hard -"@azure/identity@npm:^2.0.1, @azure/identity@npm:^2.0.4, @azure/identity@npm:^2.1.0": +"@azure/identity@npm:^2.0.4, @azure/identity@npm:^2.1.0": version: 2.1.0 resolution: "@azure/identity@npm:2.1.0" dependencies: @@ -7598,7 +7598,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-techdocs-node@workspace:plugins/techdocs-node" dependencies: - "@azure/identity": ^2.0.1 + "@azure/identity": ^2.1.0 "@azure/storage-blob": ^12.5.0 "@backstage/backend-common": "workspace:^" "@backstage/catalog-model": "workspace:^" From 0a61aab1723b8e3359f7b2647e1cd4713eb0dd1b Mon Sep 17 00:00:00 2001 From: Morgan Date: Wed, 23 Nov 2022 15:46:02 +0100 Subject: [PATCH 80/83] add changeset. Oh my, those poor baboons Signed-off-by: Morgan --- .changeset/forty-baboons-burn.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/forty-baboons-burn.md diff --git a/.changeset/forty-baboons-burn.md b/.changeset/forty-baboons-burn.md new file mode 100644 index 0000000000..f54b0871c4 --- /dev/null +++ b/.changeset/forty-baboons-burn.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs-node': patch +--- + +Bump dependency @azure/identity to next minor From 31fdd0dbf26a99148f8ec491cb13f3f38c714df4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 23 Nov 2022 14:55:36 +0000 Subject: [PATCH 81/83] Update dependency zod-to-json-schema to v3.19.1 Signed-off-by: Renovate Bot --- yarn.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/yarn.lock b/yarn.lock index 8a9cdcf07d..8e9d159818 100644 --- a/yarn.lock +++ b/yarn.lock @@ -38129,11 +38129,11 @@ __metadata: linkType: hard "zod-to-json-schema@npm:^3.18.1": - version: 3.18.1 - resolution: "zod-to-json-schema@npm:3.18.1" + version: 3.19.1 + resolution: "zod-to-json-schema@npm:3.19.1" peerDependencies: - zod: ^3.18.0 - checksum: e55d0de83b50fbd1caa7541d037858815964477b52a9e6495496e447107386cf16e2c08b007fcfbffd7fbe069ca2c19018425a53eaee36aff5dda942d3db71f4 + zod: ^3.19.0 + checksum: 22c07668e3c28c9d7c9bd3ad04a354ea017b6fc8b4df77ed29d11e42c4c03181612319db374932a1f8b5c37ef861157938dced9d848cad5281ee1540a156995c languageName: node linkType: hard From 79436b5120a020bc8d4dfb8b657dd9c7c34ab94f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 23 Nov 2022 15:37:09 +0000 Subject: [PATCH 82/83] Update helm/kind-action action to v1.4.0 Signed-off-by: Renovate Bot --- .github/workflows/verify_kubernetes.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/verify_kubernetes.yml b/.github/workflows/verify_kubernetes.yml index b92deb96ac..eb6bb19fea 100644 --- a/.github/workflows/verify_kubernetes.yml +++ b/.github/workflows/verify_kubernetes.yml @@ -33,7 +33,7 @@ jobs: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} - name: bootstrap kind - uses: helm/kind-action@v1.3.0 + uses: helm/kind-action@v1.4.0 - name: kubernetes test working-directory: packages/backend-common From 863bac523dfe89ecc6f9b0c486c1a00ddf26db5a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 24 Nov 2022 11:05:18 +0000 Subject: [PATCH 83/83] Update backstage/actions action to v0.5.8 Signed-off-by: Renovate Bot --- .github/workflows/ci.yml | 6 +++--- .github/workflows/cron.yml | 2 +- .github/workflows/deploy_nightly.yml | 2 +- .github/workflows/deploy_packages.yml | 4 ++-- .github/workflows/issue.yaml | 2 +- .github/workflows/pr-review-comment.yaml | 2 +- .github/workflows/pr.yaml | 2 +- .github/workflows/sync_code-formatting.yml | 2 +- .github/workflows/sync_snyk-github-issues.yml | 2 +- .github/workflows/verify_e2e-linux.yml | 2 +- .github/workflows/verify_kubernetes.yml | 2 +- .github/workflows/verify_storybook.yml | 2 +- 12 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eef5058690..7cc5874184 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,7 +33,7 @@ jobs: registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@v0.5.7 + uses: backstage/actions/yarn-install@v0.5.8 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} @@ -63,7 +63,7 @@ jobs: registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@v0.5.7 + uses: backstage/actions/yarn-install@v0.5.8 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} @@ -181,7 +181,7 @@ jobs: registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@v0.5.7 + uses: backstage/actions/yarn-install@v0.5.8 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} diff --git a/.github/workflows/cron.yml b/.github/workflows/cron.yml index 4629d656ce..2d28c242ee 100644 --- a/.github/workflows/cron.yml +++ b/.github/workflows/cron.yml @@ -8,7 +8,7 @@ jobs: cron: runs-on: ubuntu-latest steps: - - uses: backstage/actions/cron@v0.5.7 + - uses: backstage/actions/cron@v0.5.8 with: app-id: ${{ secrets.BACKSTAGE_GOALIE_APPLICATION_ID }} private-key: ${{ secrets.BACKSTAGE_GOALIE_PRIVATE_KEY }} diff --git a/.github/workflows/deploy_nightly.yml b/.github/workflows/deploy_nightly.yml index 360a74e012..053f3db621 100644 --- a/.github/workflows/deploy_nightly.yml +++ b/.github/workflows/deploy_nightly.yml @@ -26,7 +26,7 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@v0.5.7 + uses: backstage/actions/yarn-install@v0.5.8 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} diff --git a/.github/workflows/deploy_packages.yml b/.github/workflows/deploy_packages.yml index 1d03c210cd..1ee10e83d3 100644 --- a/.github/workflows/deploy_packages.yml +++ b/.github/workflows/deploy_packages.yml @@ -67,7 +67,7 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@v0.5.7 + uses: backstage/actions/yarn-install@v0.5.8 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} @@ -145,7 +145,7 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@v0.5.7 + uses: backstage/actions/yarn-install@v0.5.8 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} diff --git a/.github/workflows/issue.yaml b/.github/workflows/issue.yaml index a42b9b6f7b..e7582bd788 100644 --- a/.github/workflows/issue.yaml +++ b/.github/workflows/issue.yaml @@ -10,4 +10,4 @@ jobs: if: github.repository == 'backstage/backstage' steps: - name: Issue sync - uses: backstage/actions/issue-sync@v0.5.7 + uses: backstage/actions/issue-sync@v0.5.8 diff --git a/.github/workflows/pr-review-comment.yaml b/.github/workflows/pr-review-comment.yaml index b51d73c4ad..e3988a898d 100644 --- a/.github/workflows/pr-review-comment.yaml +++ b/.github/workflows/pr-review-comment.yaml @@ -35,7 +35,7 @@ jobs: const prNumber = artifact.name.slice('pr_number-'.length) core.setOutput('pr-number', prNumber); - - uses: backstage/actions/re-review@v0.5.7 + - uses: backstage/actions/re-review@v0.5.8 with: app-id: ${{ secrets.BACKSTAGE_GOALIE_APPLICATION_ID }} private-key: ${{ secrets.BACKSTAGE_GOALIE_PRIVATE_KEY }} diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 4ab7da8e07..54fcf2e74b 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -18,7 +18,7 @@ jobs: if: github.repository == 'backstage/backstage' && ( github.event.pull_request || github.event.issue.pull_request ) steps: - name: PR sync - uses: backstage/actions/pr-sync@v0.5.7 + uses: backstage/actions/pr-sync@v0.5.8 with: github-token: ${{ secrets.GH_SERVICE_ACCOUNT_TOKEN }} app-id: ${{ secrets.BACKSTAGE_GOALIE_APPLICATION_ID }} diff --git a/.github/workflows/sync_code-formatting.yml b/.github/workflows/sync_code-formatting.yml index 2113efe924..45c84e298a 100644 --- a/.github/workflows/sync_code-formatting.yml +++ b/.github/workflows/sync_code-formatting.yml @@ -20,7 +20,7 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@v0.5.7 + uses: backstage/actions/yarn-install@v0.5.8 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} diff --git a/.github/workflows/sync_snyk-github-issues.yml b/.github/workflows/sync_snyk-github-issues.yml index c1fb727c33..7b01757ba7 100644 --- a/.github/workflows/sync_snyk-github-issues.yml +++ b/.github/workflows/sync_snyk-github-issues.yml @@ -23,7 +23,7 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@v0.5.7 + uses: backstage/actions/yarn-install@v0.5.8 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} diff --git a/.github/workflows/verify_e2e-linux.yml b/.github/workflows/verify_e2e-linux.yml index a84b315e33..8d296041b7 100644 --- a/.github/workflows/verify_e2e-linux.yml +++ b/.github/workflows/verify_e2e-linux.yml @@ -52,7 +52,7 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@v0.5.7 + uses: backstage/actions/yarn-install@v0.5.8 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} diff --git a/.github/workflows/verify_kubernetes.yml b/.github/workflows/verify_kubernetes.yml index eb6bb19fea..a50f817020 100644 --- a/.github/workflows/verify_kubernetes.yml +++ b/.github/workflows/verify_kubernetes.yml @@ -28,7 +28,7 @@ jobs: registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@v0.5.7 + uses: backstage/actions/yarn-install@v0.5.8 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} diff --git a/.github/workflows/verify_storybook.yml b/.github/workflows/verify_storybook.yml index 4fe39fe244..b3bd850937 100644 --- a/.github/workflows/verify_storybook.yml +++ b/.github/workflows/verify_storybook.yml @@ -35,7 +35,7 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@v0.5.7 + uses: backstage/actions/yarn-install@v0.5.8 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} - name: storybook yarn install