From e2083dfb55e6b5b211ae16b40fa9d10332c6d181 Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Wed, 27 Dec 2023 12:11:26 -0600 Subject: [PATCH 01/18] Added alpha support for the New Frontend System Signed-off-by: Andre Wanlin --- .changeset/beige-apples-press.md | 5 ++ packages/app-next/app-config.yaml | 7 +- plugins/azure-devops/api-report-alpha.md | 13 +++ plugins/azure-devops/package.json | 21 ++++- plugins/azure-devops/src/alpha.ts | 18 ++++ plugins/azure-devops/src/alpha/index.ts | 17 ++++ plugins/azure-devops/src/alpha/plugin.tsx | 104 ++++++++++++++++++++++ yarn.lock | 2 + 8 files changed, 183 insertions(+), 4 deletions(-) create mode 100644 .changeset/beige-apples-press.md create mode 100644 plugins/azure-devops/api-report-alpha.md create mode 100644 plugins/azure-devops/src/alpha.ts create mode 100644 plugins/azure-devops/src/alpha/index.ts create mode 100644 plugins/azure-devops/src/alpha/plugin.tsx diff --git a/.changeset/beige-apples-press.md b/.changeset/beige-apples-press.md new file mode 100644 index 0000000000..56c46db830 --- /dev/null +++ b/.changeset/beige-apples-press.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-azure-devops': patch +--- + +Added alpha support for the New Frontend System (Declarative Integration) diff --git a/packages/app-next/app-config.yaml b/packages/app-next/app-config.yaml index 9cc3507fa4..2ffc8967e3 100644 --- a/packages/app-next/app-config.yaml +++ b/packages/app-next/app-config.yaml @@ -17,8 +17,13 @@ app: config: filter: kind:component has:links - entity-card:linguist/languages + - entity-card:azure-devops/readme # Entity page content - entity-content:techdocs + - entity-content:azure-devops/pipelines + - entity-content:azure-devops/pull-requests + - entity-content:azure-devops/git-tags + # scmAuthExtension: >- # createScmAuthExtension({ @@ -32,7 +37,7 @@ app: # }) # externalRouteRefs: - # bind(catalogPlugin.externalRoutes, { + # bind(catalogPlugin.externalRoutes, # createComponent: scaffolderPlugin.routes.root, # viewTechDoc: techdocsPlugin.routes.docRoot, # createFromTemplate: scaffolderPlugin.routes.selectedTemplate, diff --git a/plugins/azure-devops/api-report-alpha.md b/plugins/azure-devops/api-report-alpha.md new file mode 100644 index 0000000000..8040c0235f --- /dev/null +++ b/plugins/azure-devops/api-report-alpha.md @@ -0,0 +1,13 @@ +## API Report File for "@backstage/plugin-azure-devops" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackstagePlugin } from '@backstage/frontend-plugin-api'; + +// @alpha (undocumented) +const _default: BackstagePlugin<{}, {}>; +export default _default; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/azure-devops/package.json b/plugins/azure-devops/package.json index d0b5932b31..e367cfb89f 100644 --- a/plugins/azure-devops/package.json +++ b/plugins/azure-devops/package.json @@ -5,9 +5,22 @@ "types": "src/index.ts", "license": "Apache-2.0", "publishConfig": { - "access": "public", - "main": "dist/index.esm.js", - "types": "dist/index.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "frontend-plugin" @@ -30,9 +43,11 @@ }, "dependencies": { "@backstage/catalog-model": "workspace:^", + "@backstage/core-compat-api": "workspace:^", "@backstage/core-components": "workspace:^", "@backstage/core-plugin-api": "workspace:^", "@backstage/errors": "workspace:^", + "@backstage/frontend-plugin-api": "workspace:^", "@backstage/plugin-azure-devops-common": "workspace:^", "@backstage/plugin-catalog-react": "workspace:^", "@material-ui/core": "^4.12.2", diff --git a/plugins/azure-devops/src/alpha.ts b/plugins/azure-devops/src/alpha.ts new file mode 100644 index 0000000000..e80f131817 --- /dev/null +++ b/plugins/azure-devops/src/alpha.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './alpha/index'; +export { default } from './alpha/index'; diff --git a/plugins/azure-devops/src/alpha/index.ts b/plugins/azure-devops/src/alpha/index.ts new file mode 100644 index 0000000000..2f137f09ee --- /dev/null +++ b/plugins/azure-devops/src/alpha/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { default } from './plugin'; diff --git a/plugins/azure-devops/src/alpha/plugin.tsx b/plugins/azure-devops/src/alpha/plugin.tsx new file mode 100644 index 0000000000..f30b5cf219 --- /dev/null +++ b/plugins/azure-devops/src/alpha/plugin.tsx @@ -0,0 +1,104 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { + createApiExtension, + createApiFactory, + createPageExtension, + createPlugin, + discoveryApiRef, + identityApiRef, +} from '@backstage/frontend-plugin-api'; +import { azureDevOpsApiRef, AzureDevOpsClient } from '../api'; +import { + compatWrapper, + convertLegacyRouteRef, +} from '@backstage/core-compat-api'; +import { + createEntityCardExtension, + createEntityContentExtension, +} from '@backstage/plugin-catalog-react/alpha'; +import { azurePullRequestDashboardRouteRef } from '../routes'; + +export const azureDevOpsApi = createApiExtension({ + factory: createApiFactory({ + api: azureDevOpsApiRef, + deps: { discoveryApi: discoveryApiRef, identityApi: identityApiRef }, + factory: ({ discoveryApi, identityApi }) => + new AzureDevOpsClient({ discoveryApi, identityApi }), + }), +}); + +const azureDevOpsPullRequestPage = createPageExtension({ + defaultPath: '/azure-pull-requests', + routeRef: convertLegacyRouteRef(azurePullRequestDashboardRouteRef), + loader: () => + import('../components/PullRequestsPage').then(m => + compatWrapper(), + ), +}); + +const entityAzurePipelinesContent = createEntityContentExtension({ + name: 'pipelines', + defaultPath: '/pipelines', + defaultTitle: 'Pipelines', + loader: () => + import('../components/EntityPageAzurePipelines').then(m => + compatWrapper(), + ), +}); + +const entityAzureGitTagsContent = createEntityContentExtension({ + name: 'git-tags', + defaultPath: '/git-tags', + defaultTitle: 'Git Tags', + loader: () => + import('../components/EntityPageAzureGitTags').then(m => + compatWrapper(), + ), +}); + +const entityAzurePullRequestsContent = createEntityContentExtension({ + name: 'pull-requests', + defaultPath: '/pull-requests', + defaultTitle: 'Pull Requests', + loader: () => + import('../components/EntityPageAzurePullRequests').then(m => + compatWrapper(), + ), +}); + +export const entityAzureReadmeCard = createEntityCardExtension({ + name: 'readme', + loader: async () => + import('../components/ReadmeCard').then(m => + compatWrapper(), + ), +}); + +/** @alpha */ +export default createPlugin({ + id: 'azure-devops', + extensions: [ + azureDevOpsApi, + entityAzureReadmeCard, + entityAzurePipelinesContent, + entityAzureGitTagsContent, + entityAzurePullRequestsContent, + azureDevOpsPullRequestPage, + ], +}); diff --git a/yarn.lock b/yarn.lock index 42811acc21..9649405700 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4909,10 +4909,12 @@ __metadata: dependencies: "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" + "@backstage/core-compat-api": "workspace:^" "@backstage/core-components": "workspace:^" "@backstage/core-plugin-api": "workspace:^" "@backstage/dev-utils": "workspace:^" "@backstage/errors": "workspace:^" + "@backstage/frontend-plugin-api": "workspace:^" "@backstage/plugin-azure-devops-common": "workspace:^" "@backstage/plugin-catalog-react": "workspace:^" "@backstage/test-utils": "workspace:^" From e6bb058f8d1a205dde05ffdfa645a65d62d65dc4 Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Wed, 27 Dec 2023 12:58:21 -0600 Subject: [PATCH 02/18] Clean up Signed-off-by: Andre Wanlin --- packages/app-next/app-config.yaml | 3 +-- plugins/azure-devops/src/alpha/plugin.tsx | 14 ++++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/packages/app-next/app-config.yaml b/packages/app-next/app-config.yaml index 2ffc8967e3..9af6b6c438 100644 --- a/packages/app-next/app-config.yaml +++ b/packages/app-next/app-config.yaml @@ -24,7 +24,6 @@ app: - entity-content:azure-devops/pull-requests - entity-content:azure-devops/git-tags - # scmAuthExtension: >- # createScmAuthExtension({ # id: 'apis.scmAuth.addons.ghe', @@ -37,7 +36,7 @@ app: # }) # externalRouteRefs: - # bind(catalogPlugin.externalRoutes, + # bind(catalogPlugin.externalRoutes, { # createComponent: scaffolderPlugin.routes.root, # viewTechDoc: techdocsPlugin.routes.docRoot, # createFromTemplate: scaffolderPlugin.routes.selectedTemplate, diff --git a/plugins/azure-devops/src/alpha/plugin.tsx b/plugins/azure-devops/src/alpha/plugin.tsx index f30b5cf219..f601baf7c0 100644 --- a/plugins/azure-devops/src/alpha/plugin.tsx +++ b/plugins/azure-devops/src/alpha/plugin.tsx @@ -34,6 +34,7 @@ import { } from '@backstage/plugin-catalog-react/alpha'; import { azurePullRequestDashboardRouteRef } from '../routes'; +/** @alpha */ export const azureDevOpsApi = createApiExtension({ factory: createApiFactory({ api: azureDevOpsApiRef, @@ -43,7 +44,8 @@ export const azureDevOpsApi = createApiExtension({ }), }); -const azureDevOpsPullRequestPage = createPageExtension({ +/** @alpha */ +export const azureDevOpsPullRequestPage = createPageExtension({ defaultPath: '/azure-pull-requests', routeRef: convertLegacyRouteRef(azurePullRequestDashboardRouteRef), loader: () => @@ -52,7 +54,8 @@ const azureDevOpsPullRequestPage = createPageExtension({ ), }); -const entityAzurePipelinesContent = createEntityContentExtension({ +/** @alpha */ +export const entityAzurePipelinesContent = createEntityContentExtension({ name: 'pipelines', defaultPath: '/pipelines', defaultTitle: 'Pipelines', @@ -62,7 +65,8 @@ const entityAzurePipelinesContent = createEntityContentExtension({ ), }); -const entityAzureGitTagsContent = createEntityContentExtension({ +/** @alpha */ +export const entityAzureGitTagsContent = createEntityContentExtension({ name: 'git-tags', defaultPath: '/git-tags', defaultTitle: 'Git Tags', @@ -72,7 +76,8 @@ const entityAzureGitTagsContent = createEntityContentExtension({ ), }); -const entityAzurePullRequestsContent = createEntityContentExtension({ +/** @alpha */ +export const entityAzurePullRequestsContent = createEntityContentExtension({ name: 'pull-requests', defaultPath: '/pull-requests', defaultTitle: 'Pull Requests', @@ -82,6 +87,7 @@ const entityAzurePullRequestsContent = createEntityContentExtension({ ), }); +/** @alpha */ export const entityAzureReadmeCard = createEntityCardExtension({ name: 'readme', loader: async () => From a3243f206001e6567937c7858777ba772775a683 Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Sat, 27 Jan 2024 13:08:37 -0600 Subject: [PATCH 03/18] Standardized naming based on feedback Signed-off-by: Andre Wanlin --- plugins/azure-devops/src/alpha/plugin.tsx | 33 ++++++++++++----------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/plugins/azure-devops/src/alpha/plugin.tsx b/plugins/azure-devops/src/alpha/plugin.tsx index f601baf7c0..40305c1714 100644 --- a/plugins/azure-devops/src/alpha/plugin.tsx +++ b/plugins/azure-devops/src/alpha/plugin.tsx @@ -55,7 +55,7 @@ export const azureDevOpsPullRequestPage = createPageExtension({ }); /** @alpha */ -export const entityAzurePipelinesContent = createEntityContentExtension({ +export const azureDevOpsPipelinesEntityContent = createEntityContentExtension({ name: 'pipelines', defaultPath: '/pipelines', defaultTitle: 'Pipelines', @@ -66,7 +66,7 @@ export const entityAzurePipelinesContent = createEntityContentExtension({ }); /** @alpha */ -export const entityAzureGitTagsContent = createEntityContentExtension({ +export const azureDevOpsGitTagsEntityContent = createEntityContentExtension({ name: 'git-tags', defaultPath: '/git-tags', defaultTitle: 'Git Tags', @@ -77,18 +77,19 @@ export const entityAzureGitTagsContent = createEntityContentExtension({ }); /** @alpha */ -export const entityAzurePullRequestsContent = createEntityContentExtension({ - name: 'pull-requests', - defaultPath: '/pull-requests', - defaultTitle: 'Pull Requests', - loader: () => - import('../components/EntityPageAzurePullRequests').then(m => - compatWrapper(), - ), -}); +export const azureDevOpsPullRequestsEntityContent = + createEntityContentExtension({ + name: 'pull-requests', + defaultPath: '/pull-requests', + defaultTitle: 'Pull Requests', + loader: () => + import('../components/EntityPageAzurePullRequests').then(m => + compatWrapper(), + ), + }); /** @alpha */ -export const entityAzureReadmeCard = createEntityCardExtension({ +export const azureDevOpsReadmeEntityCard = createEntityCardExtension({ name: 'readme', loader: async () => import('../components/ReadmeCard').then(m => @@ -101,10 +102,10 @@ export default createPlugin({ id: 'azure-devops', extensions: [ azureDevOpsApi, - entityAzureReadmeCard, - entityAzurePipelinesContent, - entityAzureGitTagsContent, - entityAzurePullRequestsContent, + azureDevOpsReadmeEntityCard, + azureDevOpsPipelinesEntityContent, + azureDevOpsGitTagsEntityContent, + azureDevOpsPullRequestsEntityContent, azureDevOpsPullRequestPage, ], }); From aa91cd69acffd06db4febf10768d9003f1fd8426 Mon Sep 17 00:00:00 2001 From: Brian Hudson Date: Mon, 29 Jan 2024 15:54:06 -0500 Subject: [PATCH 04/18] Fix safeEntityName createOrMergeEntity was replacing capital letters with -. For example "@internal/pluginApi" would result in "internal-plugin-pi". Updated to correctly handle capital letters, prefixing them with - unless they are the first character. For example "@internal/pluginApi" would result in "internal-plugin-api". Signed-off-by: Brian Hudson m> --- .changeset/calm-onions-exercise.md | 5 ++++ .../generate-catalog-info.ts | 26 ++++++++++++++++--- 2 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 .changeset/calm-onions-exercise.md diff --git a/.changeset/calm-onions-exercise.md b/.changeset/calm-onions-exercise.md new file mode 100644 index 0000000000..f1c58a173f --- /dev/null +++ b/.changeset/calm-onions-exercise.md @@ -0,0 +1,5 @@ +--- +'@backstage/repo-tools': patch +--- + +Resolved an issue with generate-catalog-info where it was replacing upper case characters with -. diff --git a/packages/repo-tools/src/commands/generate-catalog-info/generate-catalog-info.ts b/packages/repo-tools/src/commands/generate-catalog-info/generate-catalog-info.ts index b8a473c67b..c15f478bd0 100644 --- a/packages/repo-tools/src/commands/generate-catalog-info/generate-catalog-info.ts +++ b/packages/repo-tools/src/commands/generate-catalog-info/generate-catalog-info.ts @@ -165,8 +165,17 @@ async function fixCatalogInfoYaml(options: FixOptions) { relativePath('.', yamlPath), ); const safeName = packageJson.name - .replace(/[^a-z0-9_\-\.]+/g, '-') - .replace(/^[^a-z0-9]|[^a-z0-9]$/g, ''); + .replace(/^[^\w\s]|[^a-z0-9]$/g, '') + .replace(/[^A-Za-z0-9_\-.]+/g, '-') + .replace(/([A-Z])/g, (_, letter, index, original) => { + if (index !== 0) { + const previousChar = original[index - 1]; + if (previousChar !== '-') { + return `-${letter.toLowerCase()}`; + } + } + return letter.toLowerCase(); + }); let yamlJson: BackstagePackageEntity; try { @@ -241,8 +250,17 @@ function createOrMergeEntity( existingEntity: BackstagePackageEntity | Record = {}, ): BackstagePackageEntity { const safeEntityName = packageJson.name - .replace(/[^a-z0-9_\-\.]+/g, '-') - .replace(/^[^a-z0-9]|[^a-z0-9]$/g, ''); + .replace(/^[^\w\s]|[^a-z0-9]$/g, '') + .replace(/[^A-Za-z0-9_\-.]+/g, '-') + .replace(/([A-Z])/g, (_, letter, index, original) => { + if (index !== 0) { + const previousChar = original[index - 1]; + if (previousChar !== '-') { + return `-${letter.toLowerCase()}`; + } + } + return letter.toLowerCase(); + }); return { ...existingEntity, From a245fad6c75c784ae644d07c59fbc36b685337c6 Mon Sep 17 00:00:00 2001 From: Brian Hudson Date: Tue, 30 Jan 2024 07:34:38 -0500 Subject: [PATCH 05/18] Add util function and related tests Signed-off-by: Brian Hudson --- .../generate-catalog-info.ts | 29 +++------------ .../generate-catalog-info/utils.test.ts | 36 +++++++++++++++++++ .../commands/generate-catalog-info/utils.ts | 17 +++++++++ 3 files changed, 57 insertions(+), 25 deletions(-) create mode 100644 packages/repo-tools/src/commands/generate-catalog-info/utils.test.ts diff --git a/packages/repo-tools/src/commands/generate-catalog-info/generate-catalog-info.ts b/packages/repo-tools/src/commands/generate-catalog-info/generate-catalog-info.ts index c15f478bd0..1893bd25c8 100644 --- a/packages/repo-tools/src/commands/generate-catalog-info/generate-catalog-info.ts +++ b/packages/repo-tools/src/commands/generate-catalog-info/generate-catalog-info.ts @@ -33,6 +33,7 @@ import { isFulfilled, readFile, writeFile, + safeEntityName, } from './utils'; import { CodeOwnersEntry } from 'codeowners-utils'; @@ -164,18 +165,7 @@ async function fixCatalogInfoYaml(options: FixOptions) { codeowners, relativePath('.', yamlPath), ); - const safeName = packageJson.name - .replace(/^[^\w\s]|[^a-z0-9]$/g, '') - .replace(/[^A-Za-z0-9_\-.]+/g, '-') - .replace(/([A-Z])/g, (_, letter, index, original) => { - if (index !== 0) { - const previousChar = original[index - 1]; - if (previousChar !== '-') { - return `-${letter.toLowerCase()}`; - } - } - return letter.toLowerCase(); - }); + const safeName = safeEntityName(packageJson.name); let yamlJson: BackstagePackageEntity; try { @@ -249,18 +239,7 @@ function createOrMergeEntity( owner: string, existingEntity: BackstagePackageEntity | Record = {}, ): BackstagePackageEntity { - const safeEntityName = packageJson.name - .replace(/^[^\w\s]|[^a-z0-9]$/g, '') - .replace(/[^A-Za-z0-9_\-.]+/g, '-') - .replace(/([A-Z])/g, (_, letter, index, original) => { - if (index !== 0) { - const previousChar = original[index - 1]; - if (previousChar !== '-') { - return `-${letter.toLowerCase()}`; - } - } - return letter.toLowerCase(); - }); + const entityName = safeEntityName(packageJson.name); return { ...existingEntity, @@ -269,7 +248,7 @@ function createOrMergeEntity( metadata: { ...existingEntity.metadata, // Provide default name/title/description values. - name: safeEntityName, + name: entityName, title: packageJson.name, ...(packageJson.description && !existingEntity.metadata?.description ? { description: packageJson.description } diff --git a/packages/repo-tools/src/commands/generate-catalog-info/utils.test.ts b/packages/repo-tools/src/commands/generate-catalog-info/utils.test.ts new file mode 100644 index 0000000000..40c1bb1e19 --- /dev/null +++ b/packages/repo-tools/src/commands/generate-catalog-info/utils.test.ts @@ -0,0 +1,36 @@ +/* + * Copyright 2024 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 { safeEntityName } from './utils'; + +describe('utils', () => { + describe('safeEntityName', () => { + it('should remove non-alphanumeric characters at the start and end', () => { + const result = safeEntityName('%entityname$'); + expect(result).toBe('entityname'); + }); + + it('should replace non-alphanumeric characters, except - and _, with -', () => { + const result = safeEntityName('entity@#name$'); + expect(result).toBe('entity-name'); + }); + + it('should replace capital letters with - followed by the same letter in lowercase', () => { + const result = safeEntityName('EntityName'); + expect(result).toBe('entity-name'); + }); + }); +}); diff --git a/packages/repo-tools/src/commands/generate-catalog-info/utils.ts b/packages/repo-tools/src/commands/generate-catalog-info/utils.ts index b00fbd57a8..3f23b35112 100644 --- a/packages/repo-tools/src/commands/generate-catalog-info/utils.ts +++ b/packages/repo-tools/src/commands/generate-catalog-info/utils.ts @@ -48,3 +48,20 @@ export const isRejected = ( export const isFulfilled = ( input: PromiseSettledResult, ): input is PromiseFulfilledResult => input.status === 'fulfilled'; + +/** + * Generates a suitable entity name from a package name by slugifying the given package name. + * + * @param packageName - The package name to generate an entity name from. + * @returns The generated entity name, a slugified version of the package name. + */ +export const safeEntityName = (packageName: string): string => { + return packageName + .replace(/^[^\w\s]|[^a-z0-9]$/g, '') + .replace(/[^A-Za-z0-9_\-.]+/g, '-') + .replace( + /([a-z])([A-Z])/g, + (_, a, b) => `${a}-${b.toLocaleLowerCase('en-US')}`, + ) + .replace(/^(.)/, (_, a) => a.toLocaleLowerCase('en-US')); +}; From 3489d05ed43e62e8c25979526f9659505bd51ab1 Mon Sep 17 00:00:00 2001 From: Kyle Smith Date: Thu, 1 Feb 2024 19:30:23 -0600 Subject: [PATCH 06/18] feat(backend-common/FetchUrlReader): support token authentication Builds on interface enhancements introduced by #22521 to support token-based authentication in FetchUrlReader#readUrl(). Signed-off-by: Kyle Smith --- .changeset/fast-onions-own.md | 5 +++++ .../src/reading/FetchUrlReader.test.ts | 21 +++++++++++++++++++ .../src/reading/FetchUrlReader.ts | 1 + 3 files changed, 27 insertions(+) create mode 100644 .changeset/fast-onions-own.md diff --git a/.changeset/fast-onions-own.md b/.changeset/fast-onions-own.md new file mode 100644 index 0000000000..6977b035bc --- /dev/null +++ b/.changeset/fast-onions-own.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-common': patch +--- + +`FetchUrlReader#readUrl()` now supports passing an optional `token` to authenticate requests. diff --git a/packages/backend-common/src/reading/FetchUrlReader.test.ts b/packages/backend-common/src/reading/FetchUrlReader.test.ts index ad834c64ef..7b5e4ebc05 100644 --- a/packages/backend-common/src/reading/FetchUrlReader.test.ts +++ b/packages/backend-common/src/reading/FetchUrlReader.test.ts @@ -223,6 +223,27 @@ describe('FetchUrlReader', () => { ).rejects.toThrow(NotModifiedError); }); + it('should send Authorization header if token is provided', async () => { + expect.assertions(1); + + worker.use( + rest.get( + 'https://backstage.io/requires-authentication', + (req, res, ctx) => { + expect(req.headers.get('authorization')).toBe('Bearer mytoken'); + return res(ctx.status(200)); + }, + ), + ); + + await fetchUrlReader.readUrl( + 'https://backstage.io/requires-authentication', + { + token: 'mytoken', + }, + ); + }); + it('should return etag from the response', async () => { const response = await fetchUrlReader.readUrl( 'https://backstage.io/some-resource', diff --git a/packages/backend-common/src/reading/FetchUrlReader.ts b/packages/backend-common/src/reading/FetchUrlReader.ts index 90c1cf6c26..475a98ffdc 100644 --- a/packages/backend-common/src/reading/FetchUrlReader.ts +++ b/packages/backend-common/src/reading/FetchUrlReader.ts @@ -131,6 +131,7 @@ export class FetchUrlReader implements UrlReader { ...(options?.lastModifiedAfter && { 'If-Modified-Since': options.lastModifiedAfter.toUTCString(), }), + ...(options?.token && { Authorization: `Bearer ${options.token}` }), }, // TODO(freben): The signal cast is there because pre-3.x versions of // node-fetch have a very slightly deviating AbortSignal type signature. From 796d4277acaf9a9b5e9382d4512e2c8c31d13e05 Mon Sep 17 00:00:00 2001 From: Radu Ciopraga <1442639+raduciopraga@users.noreply.github.com> Date: Thu, 1 Feb 2024 22:09:16 +0100 Subject: [PATCH 07/18] Use the EntityDisplayName component for rendering Group nodes Signed-off-by: Radu Ciopraga <1442639+raduciopraga@users.noreply.github.com> --- .changeset/strong-news-develop.md | 5 ++++ .../GroupsDiagram.test.tsx | 8 ++++-- .../GroupsExplorerContent/GroupsDiagram.tsx | 13 +++++----- .../GroupsExplorerContent.test.tsx | 26 ++++++++----------- 4 files changed, 28 insertions(+), 24 deletions(-) create mode 100644 .changeset/strong-news-develop.md diff --git a/.changeset/strong-news-develop.md b/.changeset/strong-news-develop.md new file mode 100644 index 0000000000..1cbe4dda07 --- /dev/null +++ b/.changeset/strong-news-develop.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-explore': patch +--- + +Use the EntityDisplayName component for rendering Group nodes diff --git a/plugins/explore/src/components/GroupsExplorerContent/GroupsDiagram.test.tsx b/plugins/explore/src/components/GroupsExplorerContent/GroupsDiagram.test.tsx index 7c57de84bc..1329d3c522 100644 --- a/plugins/explore/src/components/GroupsExplorerContent/GroupsDiagram.test.tsx +++ b/plugins/explore/src/components/GroupsExplorerContent/GroupsDiagram.test.tsx @@ -21,6 +21,7 @@ import { } from '@backstage/plugin-catalog-react'; import { Entity } from '@backstage/catalog-model'; import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; +import { screen } from '@testing-library/react'; import React from 'react'; import { GroupsDiagram } from './GroupsDiagram'; @@ -55,7 +56,7 @@ describe('', () => { }), }; - const { getByText } = await renderInTestApp( + await renderInTestApp( , @@ -65,6 +66,9 @@ describe('', () => { }, }, ); - expect(getByText('Group A', { selector: 'div' })).toBeInTheDocument(); + + expect( + screen.getByRole('link', { name: 'group:my-namespace/group-a' }), + ).toBeInTheDocument(); }); }); diff --git a/plugins/explore/src/components/GroupsExplorerContent/GroupsDiagram.tsx b/plugins/explore/src/components/GroupsExplorerContent/GroupsDiagram.tsx index f7f0eab0bd..dd0705908a 100644 --- a/plugins/explore/src/components/GroupsExplorerContent/GroupsDiagram.tsx +++ b/plugins/explore/src/components/GroupsExplorerContent/GroupsDiagram.tsx @@ -15,7 +15,6 @@ */ import { - GroupEntity, parseEntityRef, RELATION_CHILD_OF, stringifyEntityRef, @@ -31,8 +30,8 @@ import { configApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api'; import { catalogApiRef, entityRouteRef, - humanizeEntityRef, getEntityRelations, + EntityDisplayName, } from '@backstage/plugin-catalog-react'; import { makeStyles, Typography, useTheme } from '@material-ui/core'; import ZoomOutMap from '@material-ui/icons/ZoomOutMap'; @@ -140,7 +139,9 @@ function RenderNode(props: DependencyGraphTypes.RenderNodeProps) { rx={theme.shape.borderRadius} className={classes.groupNode} /> - {props.node.name} + + <EntityDisplayName entityRef={props.node.id} hideIcon disableTooltip /> + ) {
- {props.node.name} +
@@ -210,9 +211,7 @@ export function GroupsDiagram(props: { nodes.push({ id: stringifyEntityRef(catalogItem), kind: catalogItem.kind, - name: - (catalogItem as GroupEntity).spec?.profile?.displayName || - humanizeEntityRef(catalogItem, { defaultKind: 'Group' }), + name: '', }); // Edge to parent diff --git a/plugins/explore/src/components/GroupsExplorerContent/GroupsExplorerContent.test.tsx b/plugins/explore/src/components/GroupsExplorerContent/GroupsExplorerContent.test.tsx index 9b461fba7d..0e992c220d 100644 --- a/plugins/explore/src/components/GroupsExplorerContent/GroupsExplorerContent.test.tsx +++ b/plugins/explore/src/components/GroupsExplorerContent/GroupsExplorerContent.test.tsx @@ -17,7 +17,7 @@ import { Entity } from '@backstage/catalog-model'; import { catalogApiRef, entityRouteRef } from '@backstage/plugin-catalog-react'; import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; -import { waitFor } from '@testing-library/react'; +import { screen } from '@testing-library/react'; import React from 'react'; import { GroupsExplorerContent } from '../GroupsExplorerContent'; @@ -73,48 +73,44 @@ describe('', () => { ]; catalogApi.getEntities.mockResolvedValue({ items: entities }); - const { getByText } = await renderInTestApp( + await renderInTestApp( , mountedRoutes, ); - await waitFor(() => { - expect( - getByText('my-namespace/group-a', { selector: 'div' }), - ).toBeInTheDocument(); - }); + expect( + screen.getByRole('link', { name: 'group:my-namespace/group-a' }), + ).toBeInTheDocument(); }); it('renders a custom title', async () => { catalogApi.getEntities.mockResolvedValue({ items: [] }); - const { getByText } = await renderInTestApp( + await renderInTestApp( , mountedRoutes, ); - await waitFor(() => - expect(getByText('Our Teams', { selector: 'h2' })).toBeInTheDocument(), - ); + expect( + screen.getByText('Our Teams', { selector: 'h2' }), + ).toBeInTheDocument(); }); it('renders a friendly error if it cannot collect domains', async () => { const catalogError = new Error('Network timeout'); catalogApi.getEntities.mockRejectedValueOnce(catalogError); - const { getAllByText } = await renderInTestApp( + await renderInTestApp( , mountedRoutes, ); - await waitFor(() => - expect(getAllByText(/Error: Network timeout/).length).not.toBe(0), - ); + expect(screen.getAllByText(/Error: Network timeout/).length).not.toBe(0); }); }); From 43766556fb3e30b8dbd545285333c45a5ccf4915 Mon Sep 17 00:00:00 2001 From: Deepankumar Loganathan Date: Sun, 4 Feb 2024 16:49:58 +0100 Subject: [PATCH 08/18] Added permissionIntegrationRouter for azure-sites-backend routes Signed-off-by: Deepankumar Loganathan --- .changeset/tall-frogs-clap.md | 5 +++++ plugins/azure-sites-backend/src/service/router.ts | 7 +++++++ 2 files changed, 12 insertions(+) create mode 100644 .changeset/tall-frogs-clap.md diff --git a/.changeset/tall-frogs-clap.md b/.changeset/tall-frogs-clap.md new file mode 100644 index 0000000000..1e87ca316c --- /dev/null +++ b/.changeset/tall-frogs-clap.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-azure-sites-backend': patch +--- + +Added `permissionIntegrationRouter` for azure-sites-backend routes diff --git a/plugins/azure-sites-backend/src/service/router.ts b/plugins/azure-sites-backend/src/service/router.ts index 9ed198cc20..bd5d20c05e 100644 --- a/plugins/azure-sites-backend/src/service/router.ts +++ b/plugins/azure-sites-backend/src/service/router.ts @@ -27,8 +27,10 @@ import { } from '@backstage/plugin-permission-common'; import { azureSitesActionPermission, + azureSitesPermissions, AZURE_WEB_SITE_NAME_ANNOTATION, } from '@backstage/plugin-azure-sites-common'; +import { createPermissionIntegrationRouter } from '@backstage/plugin-permission-node'; import { CatalogApi } from '@backstage/catalog-client'; import { AzureSitesApi } from '../api'; @@ -47,8 +49,13 @@ export async function createRouter( ): Promise { const { logger, azureSitesApi, permissions, catalogApi } = options; + const permissionIntegrationRouter = createPermissionIntegrationRouter({ + permissions: azureSitesPermissions, + }); + const router = Router(); router.use(express.json()); + router.use(permissionIntegrationRouter); router.get('/health', (_, response) => { logger.info('PONG!'); From 6178a67e838500a49f1f591c451676d868b3be33 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 4 Feb 2024 17:02:06 +0000 Subject: [PATCH 09/18] chore(deps): update dependency husky to v9 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 6deae7611e..4a90b25e7b 100644 --- a/package.json +++ b/package.json @@ -85,7 +85,7 @@ "eslint-plugin-react": "^7.28.0", "eslint-plugin-testing-library": "^6.0.0", "fs-extra": "10.1.0", - "husky": "^8.0.0", + "husky": "^9.0.0", "lint-staged": "^15.0.0", "minimist": "^1.2.5", "node-gyp": "^10.0.0", diff --git a/yarn.lock b/yarn.lock index 5f84cbbc51..868817d2e8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -29839,12 +29839,12 @@ __metadata: languageName: node linkType: hard -"husky@npm:^8.0.0": - version: 8.0.3 - resolution: "husky@npm:8.0.3" +"husky@npm:^9.0.0": + version: 9.0.10 + resolution: "husky@npm:9.0.10" bin: - husky: lib/bin.js - checksum: 837bc7e4413e58c1f2946d38fb050f5d7324c6f16b0fd66411ffce5703b294bd21429e8ba58711cd331951ee86ed529c5be4f76805959ff668a337dbfa82a1b0 + husky: bin.mjs + checksum: 55f4b6db6706ff0bc181607d6a64f55310cbb18b4d7db2a5b85608c87a80abafc14ac3a8c4d0b44d6272f4a62d4c2d3d5491d6a13e2cc7ac4895309e5e5f0ec2 languageName: node linkType: hard @@ -40403,7 +40403,7 @@ __metadata: eslint-plugin-react: ^7.28.0 eslint-plugin-testing-library: ^6.0.0 fs-extra: 10.1.0 - husky: ^8.0.0 + husky: ^9.0.0 lint-staged: ^15.0.0 minimist: ^1.2.5 node-gyp: ^10.0.0 From 742e0fefde56f7cd4e42cb49fcf53b0ae5d6bdac Mon Sep 17 00:00:00 2001 From: Frida Jacobsson Date: Mon, 5 Feb 2024 09:09:35 +0100 Subject: [PATCH 10/18] Adding Umami analytics plugin to microsite Signed-off-by: Frida Jacobsson --- microsite/data/plugins/umami.yaml | 10 ++++++++++ microsite/static/img/umami-logo.svg | 1 + 2 files changed, 11 insertions(+) create mode 100644 microsite/data/plugins/umami.yaml create mode 100644 microsite/static/img/umami-logo.svg diff --git a/microsite/data/plugins/umami.yaml b/microsite/data/plugins/umami.yaml new file mode 100644 index 0000000000..308b09c90c --- /dev/null +++ b/microsite/data/plugins/umami.yaml @@ -0,0 +1,10 @@ +--- +title: Umami Analytics +author: AxisCommunications +authorUrl: https://github.com/AxisCommunications +category: Monitoring +description: Track usage of your Backstage instance using Umami Analytics. +documentation: https://github.com/AxisCommunications/backstage-plugins/blob/main/plugins/analytics-module-umami/README.md +iconUrl: /img/umami-logo.svg +npmPackageName: '@axis-backstage/plugin-analytics-module-umami' +addedDate: '2024-02-05' \ No newline at end of file diff --git a/microsite/static/img/umami-logo.svg b/microsite/static/img/umami-logo.svg new file mode 100644 index 0000000000..b139531324 --- /dev/null +++ b/microsite/static/img/umami-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file From 307474d1a3831d617d2ab9f8506f5f4c7f45e53a Mon Sep 17 00:00:00 2001 From: Frida Jacobsson Date: Mon, 5 Feb 2024 10:17:24 +0100 Subject: [PATCH 11/18] Run prettier Signed-off-by: Frida Jacobsson --- microsite/data/plugins/umami.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/microsite/data/plugins/umami.yaml b/microsite/data/plugins/umami.yaml index 308b09c90c..5f1fc208d4 100644 --- a/microsite/data/plugins/umami.yaml +++ b/microsite/data/plugins/umami.yaml @@ -7,4 +7,4 @@ description: Track usage of your Backstage instance using Umami Analytics. documentation: https://github.com/AxisCommunications/backstage-plugins/blob/main/plugins/analytics-module-umami/README.md iconUrl: /img/umami-logo.svg npmPackageName: '@axis-backstage/plugin-analytics-module-umami' -addedDate: '2024-02-05' \ No newline at end of file +addedDate: '2024-02-05' From 7fb7a79dce0b40260ffabfde3621eea6b3dddd01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Mon, 5 Feb 2024 13:11:46 +0100 Subject: [PATCH 12/18] add a config declaration for workingDirectory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/wise-papayas-cough.md | 5 +++++ packages/backend-common/config.d.ts | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 .changeset/wise-papayas-cough.md diff --git a/.changeset/wise-papayas-cough.md b/.changeset/wise-papayas-cough.md new file mode 100644 index 0000000000..955e7fefcc --- /dev/null +++ b/.changeset/wise-papayas-cough.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-common': patch +--- + +Add a config declaration for `workingDirectory` diff --git a/packages/backend-common/config.d.ts b/packages/backend-common/config.d.ts index 8bcc5465d5..700d9a6c6c 100644 --- a/packages/backend-common/config.d.ts +++ b/packages/backend-common/config.d.ts @@ -67,6 +67,22 @@ export interface Config { }; }; + /** + * An absolute path to a directory that can be used as a working dir, for + * example as scratch space for large operations. + * + * @remarks + * + * Note that this must be an absolute path. + * + * If not set, the operating system's designated temporary directory is + * commonly used, but that is implementation defined per plugin. + * + * Plugins are encouraged to heed this config setting if present, to allow + * deployment in severely locked-down or limited environments. + */ + workingDirectory?: string; + /** Database connection configuration, select base database type using the `client` field */ database: { /** Default database client to use */ From 501b750fa27f1874c652446dda7be4bbbfb81e8e Mon Sep 17 00:00:00 2001 From: Radu Ciopraga <1442639+raduciopraga@users.noreply.github.com> Date: Mon, 5 Feb 2024 21:23:20 +0100 Subject: [PATCH 13/18] wait for GroupsExplorerContent test expectations to pass Signed-off-by: Radu Ciopraga <1442639+raduciopraga@users.noreply.github.com> --- .../GroupsExplorerContent.test.tsx | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/plugins/explore/src/components/GroupsExplorerContent/GroupsExplorerContent.test.tsx b/plugins/explore/src/components/GroupsExplorerContent/GroupsExplorerContent.test.tsx index 0e992c220d..00a6164aa9 100644 --- a/plugins/explore/src/components/GroupsExplorerContent/GroupsExplorerContent.test.tsx +++ b/plugins/explore/src/components/GroupsExplorerContent/GroupsExplorerContent.test.tsx @@ -17,7 +17,7 @@ import { Entity } from '@backstage/catalog-model'; import { catalogApiRef, entityRouteRef } from '@backstage/plugin-catalog-react'; import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; -import { screen } from '@testing-library/react'; +import { waitFor, screen } from '@testing-library/react'; import React from 'react'; import { GroupsExplorerContent } from '../GroupsExplorerContent'; @@ -80,9 +80,11 @@ describe('', () => { mountedRoutes, ); - expect( - screen.getByRole('link', { name: 'group:my-namespace/group-a' }), - ).toBeInTheDocument(); + await waitFor(() => + expect( + screen.getByRole('link', { name: 'group:my-namespace/group-a' }), + ).toBeInTheDocument(), + ); }); it('renders a custom title', async () => { @@ -95,9 +97,11 @@ describe('', () => { mountedRoutes, ); - expect( - screen.getByText('Our Teams', { selector: 'h2' }), - ).toBeInTheDocument(); + await waitFor(() => + expect( + screen.getByText('Our Teams', { selector: 'h2' }), + ).toBeInTheDocument(), + ); }); it('renders a friendly error if it cannot collect domains', async () => { @@ -111,6 +115,8 @@ describe('', () => { mountedRoutes, ); - expect(screen.getAllByText(/Error: Network timeout/).length).not.toBe(0); + await waitFor(() => + expect(screen.getAllByText(/Error: Network timeout/).length).not.toBe(0), + ); }); }); From 10f0efdcb7a47a530a4571bb286f370567af3699 Mon Sep 17 00:00:00 2001 From: Heikki Hellgren Date: Tue, 6 Feb 2024 08:14:00 +0200 Subject: [PATCH 14/18] test: fix failing template card test Signed-off-by: Heikki Hellgren --- .../components/TemplateCard/TemplateCard.test.tsx | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.test.tsx b/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.test.tsx index 9ff1dd1b17..ec4e4e1b0a 100644 --- a/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.test.tsx +++ b/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.test.tsx @@ -358,12 +358,11 @@ describe('TemplateCard', () => { }, ); - expect( - getByRole('link', { name: 'group:default/my-test-user' }), - ).toBeInTheDocument(); - expect( - getByRole('link', { name: 'group:default/my-test-user' }), - ).toHaveAttribute('href', '/catalog/group/default/my-test-user'); + expect(getByRole('link', { name: /.*my-test-user$/ })).toBeInTheDocument(); + expect(getByRole('link', { name: /.*my-test-user$/ })).toHaveAttribute( + 'href', + '/catalog/group/default/my-test-user', + ); }); it('should call the onSelected handler when clicking the choose button', async () => { From d5b14a0ad52bf362904d1af9c36c0ac1b5b68cb4 Mon Sep 17 00:00:00 2001 From: AmbrishRamachandiran Date: Tue, 6 Feb 2024 12:19:15 +0530 Subject: [PATCH 15/18] conditionally rendering the user name and email in user settings page Signed-off-by: AmbrishRamachandiran --- .changeset/shiny-clocks-greet.md | 5 ++++ .../AuthProviders/ProviderSettingsItem.tsx | 24 +++++++++++-------- 2 files changed, 19 insertions(+), 10 deletions(-) create mode 100644 .changeset/shiny-clocks-greet.md diff --git a/.changeset/shiny-clocks-greet.md b/.changeset/shiny-clocks-greet.md new file mode 100644 index 0000000000..0c112ff81f --- /dev/null +++ b/.changeset/shiny-clocks-greet.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-user-settings': patch +--- + +conditionally rendering the user name and email in user settings page diff --git a/plugins/user-settings/src/components/AuthProviders/ProviderSettingsItem.tsx b/plugins/user-settings/src/components/AuthProviders/ProviderSettingsItem.tsx index e3fb597a15..e9a710036f 100644 --- a/plugins/user-settings/src/components/AuthProviders/ProviderSettingsItem.tsx +++ b/plugins/user-settings/src/components/AuthProviders/ProviderSettingsItem.tsx @@ -101,16 +101,20 @@ export const ProviderSettingsItem = (props: { - - {profile.displayName} - - - {profile.email} - + {profile.displayName && ( + + {profile.displayName} + + )} + {profile.email && ( + + {profile.email} + + )} {description} From b8651e1316043d55988da7927eda36aa1f15791a Mon Sep 17 00:00:00 2001 From: hubofgitongithub <156336979+hubofgitongithub@users.noreply.github.com> Date: Tue, 6 Feb 2024 09:33:24 +0100 Subject: [PATCH 16/18] Update core-compat-api package.json with repo information To fix https://www.npmjs.com/package/@backstage/core-compat-api having a source code URL location (and thus fixing security scanners triggering on that information missing). Signed-off-by: hubofgitongithub <156336979+hubofgitongithub@users.noreply.github.com> --- packages/core-compat-api/package.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/core-compat-api/package.json b/packages/core-compat-api/package.json index dff05e9774..51d4bcdf4c 100644 --- a/packages/core-compat-api/package.json +++ b/packages/core-compat-api/package.json @@ -12,6 +12,11 @@ "backstage": { "role": "web-library" }, + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "packages/core-compat-api" + }, "sideEffects": false, "scripts": { "start": "backstage-cli package start", From ad2444c8dad22419dfaaa27ac49e4c88180d52a0 Mon Sep 17 00:00:00 2001 From: hubofgitongithub <156336979+hubofgitongithub@users.noreply.github.com> Date: Tue, 6 Feb 2024 09:38:18 +0100 Subject: [PATCH 17/18] Update frontend-plugin-api package.json with repo information To fix https://www.npmjs.com/package/@backstage/frontend-plugin-api having a source code URL location (and thus fixing security scanners triggering on that information missing). Signed-off-by: hubofgitongithub <156336979+hubofgitongithub@users.noreply.github.com> --- packages/frontend-plugin-api/package.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/frontend-plugin-api/package.json b/packages/frontend-plugin-api/package.json index 7d8009f338..7d5b99d504 100644 --- a/packages/frontend-plugin-api/package.json +++ b/packages/frontend-plugin-api/package.json @@ -12,6 +12,11 @@ "backstage": { "role": "web-library" }, + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "packages/frontend-plugin-api" + }, "sideEffects": false, "scripts": { "start": "backstage-cli package start", From 0e934d1e9162873ccd2235e9c7d191f8fb4e7068 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Tue, 6 Feb 2024 11:09:16 +0100 Subject: [PATCH 18/18] migrate to husky v9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .husky/pre-commit | 3 --- package.json | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/.husky/pre-commit b/.husky/pre-commit index d2ae35e84b..3723623171 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1 @@ -#!/bin/sh -. "$(dirname "$0")/_/husky.sh" - yarn lint-staged diff --git a/package.json b/package.json index 4a90b25e7b..fbe47ec8b4 100644 --- a/package.json +++ b/package.json @@ -40,8 +40,8 @@ "build-storybook": "yarn ./storybook run build-storybook", "techdocs-cli": "node scripts/techdocs-cli.js", "techdocs-cli:dev": "cross-env TECHDOCS_CLI_DEV_MODE=true node scripts/techdocs-cli.js", - "prepare": "husky install", - "postinstall": "husky install || true" + "prepare": "husky", + "postinstall": "husky || true" }, "workspaces": { "packages": [