From 0e39d0b4fe32ca0504abb539a8ae68248f695889 Mon Sep 17 00:00:00 2001 From: Eric Peterson Date: Fri, 4 Mar 2022 10:51:03 +0100 Subject: [PATCH 01/12] Update documentation to reflect search beta. Signed-off-by: Eric Peterson --- docs/features/search/README.md | 12 ++++++------ docs/features/search/how-to-guides.md | 18 +++++++++++------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/docs/features/search/README.md b/docs/features/search/README.md index 0856451882..f25087d59b 100644 --- a/docs/features/search/README.md +++ b/docs/features/search/README.md @@ -24,12 +24,12 @@ Backstage ecosystem. ## Project roadmap -| Version | Description | -| -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Backstage Search Pre-Alpha ✅ | Search Frontend letting you search through the entities of the software catalog. [See Pre-Alpha Use Cases.](#backstage-search-pre-alpha) | -| Backstage Search Alpha ✅ | Basic “out-of-the-box” in-memory indexing process of entities, and their metadata, registered to the Software Catalog. [See Alpha Use Cases](#backstage-search-alpha). | -| [Backstage Search Beta ⌛][beta] | At least one production-ready search engine that supports the same use-cases as in the alpha. [See Beta Use Cases](#backstage-search-beta). | -| [Backstage Search GA ⌛][ga] | A stable Search API for plugin developers to add search to their plugins, and app integrators to expose that to their users. [See GA Use Cases](#backstage-search-ga). | +| Version | Description | +| ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Backstage Search Pre-Alpha ✅ | Search Frontend letting you search through the entities of the software catalog. [See Pre-Alpha Use Cases.](#backstage-search-pre-alpha) | +| Backstage Search Alpha ✅ | Basic “out-of-the-box” in-memory indexing process of entities, and their metadata, registered to the Software Catalog. [See Alpha Use Cases](#backstage-search-alpha). | +| Backstage Search Beta ✅ | At least one production-ready search engine that supports the same use-cases as in the alpha. [See Beta Use Cases](#backstage-search-beta). | +| [Backstage Search GA ⌛][ga] | A stable Search API for plugin developers to add search to their plugins, and app integrators to expose that to their users. [See GA Use Cases](#backstage-search-ga). | [beta]: https://github.com/backstage/backstage/milestone/27 [ga]: https://github.com/backstage/backstage/milestone/28 diff --git a/docs/features/search/how-to-guides.md b/docs/features/search/how-to-guides.md index 0a5f53d2f2..16596c6e92 100644 --- a/docs/features/search/how-to-guides.md +++ b/docs/features/search/how-to-guides.md @@ -137,9 +137,10 @@ entities are indexed by the search engine. For the purposes of this guide, Search Beta version is defined as: -- **Search Plugin**: At least `v0.x.y` -- **Search Backend Plugin**: At least `v0.x.y` -- **Search Backend Node**: At least `v0.x.y` +- **Search Plugin**: At least `v0.7.2` +- **Search Backend Plugin**: At least `v0.4.6` +- **Search Backend Node**: At least `v0.5.0` +- **Search Common**: At least `v0.3.0` In the Beta version, the Search Platform's indexing process has been rewritten as a stream pipeline in order to improve efficiency and performance on large @@ -149,11 +150,14 @@ If you've not yet extended the Search Platform with custom code, and have instead taken advantage of default collators, decorators, and search engines provided by existing plugins, the migration process is fairly straightforward: -1. Upgrade to at least version `0.x.y` of +1. Upgrade to at least version `0.5.0` of `@backstage/plugin-search-backend-node`, as well as any backend plugins whose - collators you are using (e.g. at least version `0.x.y` of - `@backstage/plugin-catalog-backend` and/or version `0.x.y` of - `@backstage/plugin-techdocs-backend`). + collators you are using (e.g. at least version `0.23.0` of + `@backstage/plugin-catalog-backend` and/or version `0.14.1` of + `@backstage/plugin-techdocs-backend`), as well as any search-engine specific + plugin you are using (e.g. at least version `0.3.0` of + `@backstage/plugin-search-backend-module-pg` or version `0.1.0` of + `@backstage/plugin-search-backend-module-elasticsearch`). 2. Then, make the following changes to your `/packages/backend/src/plugins/search.ts` file: From 50e69335c71198a742a8c4f2441cd3e329b1740c Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Fri, 4 Mar 2022 11:24:12 +0100 Subject: [PATCH 02/12] Trigger upgrade helper release once Signed-off-by: Vincenzo Scamporlino --- .github/workflows/sync_release-manifest.yml | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/.github/workflows/sync_release-manifest.yml b/.github/workflows/sync_release-manifest.yml index f4d9afc0df..328c64fb58 100644 --- a/.github/workflows/sync_release-manifest.yml +++ b/.github/workflows/sync_release-manifest.yml @@ -56,18 +56,7 @@ jobs: github-token: ${{ secrets.GH_SERVICE_ACCOUNT_TOKEN }} # TODO(Rugvip): Remove the create-app dispatch once we've been on the release version for a while script: | - console.log('Dispatching upgrade helper sync - release version'); - await github.rest.actions.createWorkflowDispatch({ - owner: 'backstage', - repo: 'upgrade-helper-diff', - workflow_id: 'release.yml', - ref: 'master', - inputs: { - version: require('./backstage/package.json').version, - }, - }); - - console.log('Dispatching upgrade helper sync - create-app version'); + console.log('Dispatching upgrade helper sync'); await github.rest.actions.createWorkflowDispatch({ owner: 'backstage', repo: 'upgrade-helper-diff', @@ -75,5 +64,6 @@ jobs: ref: 'master', inputs: { version: require('./backstage/packages/create-app/package.json').version, + releaseVersion: require('./backstage/package.json').version }, }); From c543fe3ff2687a12ba03d767d2976f5c8fc6da8d Mon Sep 17 00:00:00 2001 From: Eric Peterson Date: Fri, 4 Mar 2022 11:27:43 +0100 Subject: [PATCH 03/12] Respect PG selection in create-app for search. Signed-off-by: Eric Peterson --- .changeset/search-talking-in-code.md | 7 +++++++ packages/create-app/package.json | 1 + packages/create-app/src/lib/versions.ts | 2 ++ .../default-app/packages/backend/package.json.hbs | 3 +++ .../backend/src/plugins/{search.ts => search.ts.hbs} | 10 ++++++++++ packages/e2e-test/src/commands/run.ts | 12 +++++++++--- 6 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 .changeset/search-talking-in-code.md rename packages/create-app/templates/default-app/packages/backend/src/plugins/{search.ts => search.ts.hbs} (85%) diff --git a/.changeset/search-talking-in-code.md b/.changeset/search-talking-in-code.md new file mode 100644 index 0000000000..46de5f8343 --- /dev/null +++ b/.changeset/search-talking-in-code.md @@ -0,0 +1,7 @@ +--- +'@backstage/create-app': patch +--- + +Postgres-based search is now installed when PG is chosen as the desired database for Backstage. + +There is no need to make this change in an existing Backstage backend. See [supported search engines](https://backstage.io/docs/features/search/search-engines) for details about production-ready search engines. diff --git a/packages/create-app/package.json b/packages/create-app/package.json index 975d2cee7e..9fd8c33837 100644 --- a/packages/create-app/package.json +++ b/packages/create-app/package.json @@ -86,6 +86,7 @@ "@backstage/plugin-scaffolder-backend": "", "@backstage/plugin-search": "", "@backstage/plugin-search-backend": "", + "@backstage/plugin-search-backend-module-pg": "", "@backstage/plugin-search-backend-node": "", "@backstage/plugin-tech-radar": "", "@backstage/plugin-techdocs": "", diff --git a/packages/create-app/src/lib/versions.ts b/packages/create-app/src/lib/versions.ts index 7179b7924f..e79e86e3be 100644 --- a/packages/create-app/src/lib/versions.ts +++ b/packages/create-app/src/lib/versions.ts @@ -68,6 +68,7 @@ import { version as pluginScaffolder } from '../../../../plugins/scaffolder/pack import { version as pluginScaffolderBackend } from '../../../../plugins/scaffolder-backend/package.json'; import { version as pluginSearch } from '../../../../plugins/search/package.json'; import { version as pluginSearchBackend } from '../../../../plugins/search-backend/package.json'; +import { version as pluginSearchBackendModulePg } from '../../../../plugins/search-backend-module-pg/package.json'; import { version as pluginSearchBackendNode } from '../../../../plugins/search-backend-node/package.json'; import { version as pluginTechRadar } from '../../../../plugins/tech-radar/package.json'; import { version as pluginTechdocs } from '../../../../plugins/techdocs/package.json'; @@ -110,6 +111,7 @@ export const packageVersions = { '@backstage/plugin-scaffolder-backend': pluginScaffolderBackend, '@backstage/plugin-search': pluginSearch, '@backstage/plugin-search-backend': pluginSearchBackend, + '@backstage/plugin-search-backend-module-pg': pluginSearchBackendModulePg, '@backstage/plugin-search-backend-node': pluginSearchBackendNode, '@backstage/plugin-tech-radar': pluginTechRadar, '@backstage/plugin-techdocs': pluginTechdocs, diff --git a/packages/create-app/templates/default-app/packages/backend/package.json.hbs b/packages/create-app/templates/default-app/packages/backend/package.json.hbs index 5dd70286bc..feba5169ba 100644 --- a/packages/create-app/templates/default-app/packages/backend/package.json.hbs +++ b/packages/create-app/templates/default-app/packages/backend/package.json.hbs @@ -28,6 +28,9 @@ "@backstage/plugin-proxy-backend": "^{{version '@backstage/plugin-proxy-backend'}}", "@backstage/plugin-scaffolder-backend": "^{{version '@backstage/plugin-scaffolder-backend'}}", "@backstage/plugin-search-backend": "^{{version '@backstage/plugin-search-backend'}}", + {{#if dbTypePG}} + "@backstage/plugin-search-backend-module-pg": "^{{version '@backstage/plugin-search-backend-module-pg'}}", + {{/if}} "@backstage/plugin-search-backend-node": "^{{version '@backstage/plugin-search-backend-node'}}", "@backstage/plugin-techdocs-backend": "^{{version '@backstage/plugin-techdocs-backend'}}", "@gitbeaker/node": "^34.6.0", diff --git a/packages/create-app/templates/default-app/packages/backend/src/plugins/search.ts b/packages/create-app/templates/default-app/packages/backend/src/plugins/search.ts.hbs similarity index 85% rename from packages/create-app/templates/default-app/packages/backend/src/plugins/search.ts rename to packages/create-app/templates/default-app/packages/backend/src/plugins/search.ts.hbs index c359cb4986..d8ad991e8a 100644 --- a/packages/create-app/templates/default-app/packages/backend/src/plugins/search.ts +++ b/packages/create-app/templates/default-app/packages/backend/src/plugins/search.ts.hbs @@ -4,6 +4,9 @@ import { IndexBuilder, LunrSearchEngine, } from '@backstage/plugin-search-backend-node'; +{{#if dbTypePG}} +import { PgSearchEngine } from '@backstage/plugin-search-backend-module-pg'; +{{/if}} import { PluginEnvironment } from '../types'; import { DefaultCatalogCollatorFactory } from '@backstage/plugin-catalog-backend'; import { DefaultTechDocsCollatorFactory } from '@backstage/plugin-techdocs-backend'; @@ -16,7 +19,14 @@ export default async function createPlugin({ tokenManager, }: PluginEnvironment) { // Initialize a connection to a search engine. + {{#if dbTypeSqlite}} const searchEngine = new LunrSearchEngine({ logger }); + {{/if}} + {{#if dbTypePG}} + const searchEngine = (await PgSearchEngine.supported(database)) + ? await PgSearchEngine.from({ database }) + : new LunrSearchEngine({ logger }); + {{/if}} const indexBuilder = new IndexBuilder({ logger, searchEngine }); // Collators are responsible for gathering documents known to plugins. This diff --git a/packages/e2e-test/src/commands/run.ts b/packages/e2e-test/src/commands/run.ts index a7456f91dd..1ec9499b92 100644 --- a/packages/e2e-test/src/commands/run.ts +++ b/packages/e2e-test/src/commands/run.ts @@ -420,9 +420,15 @@ async function testBackendStart(appDir: string, isPostgres: boolean) { if (isPostgres) { print('Dropping old DBs'); await Promise.all( - ['catalog', 'scaffolder', 'auth', 'identity', 'proxy', 'techdocs'].map( - name => dropDB(`backstage_plugin_${name}`), - ), + [ + 'catalog', + 'scaffolder', + 'auth', + 'identity', + 'proxy', + 'techdocs', + 'search', + ].map(name => dropDB(`backstage_plugin_${name}`)), ); print('Created DBs'); } From 6a1fe077adddb347db12c4c31bafa1ba18b97938 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 4 Mar 2022 13:20:32 +0100 Subject: [PATCH 04/12] cli: switch rollup config to consider all package modules external Signed-off-by: Patrik Oldsberg --- .changeset/tender-berries-lie.md | 5 ++ docs/local-dev/cli-build-system.md | 10 ++-- packages/cli/package.json | 1 - packages/cli/src/lib/builder/config.test.ts | 59 +++++++++++++++++++++ packages/cli/src/lib/builder/config.ts | 22 +++++--- yarn.lock | 5 -- 6 files changed, 84 insertions(+), 18 deletions(-) create mode 100644 .changeset/tender-berries-lie.md create mode 100644 packages/cli/src/lib/builder/config.test.ts diff --git a/.changeset/tender-berries-lie.md b/.changeset/tender-berries-lie.md new file mode 100644 index 0000000000..74a3eb4707 --- /dev/null +++ b/.changeset/tender-berries-lie.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Changed the logic for how modules are marked as external in the Rollup build of packages. Rather than only marking dependencies and build-in Node.js modules as external, all non-relative imports are now considered external. diff --git a/docs/local-dev/cli-build-system.md b/docs/local-dev/cli-build-system.md index f57efc1255..aed3ba70bc 100644 --- a/docs/local-dev/cli-build-system.md +++ b/docs/local-dev/cli-build-system.md @@ -181,12 +181,10 @@ files like stylesheets or images. For more details on what syntax and file formats are supported by the build process, see the [loaders section](#loaders). When building CommonJS or ESM output, the build commands will always use -`src/index.ts` as the entrypoint. All dependencies of the package will be marked -as external, meaning that in general it is only the contents of the `src` folder -that ends up being compiled and output to `dist`. All import statements of -external dependencies, even within the same monorepo, will stay intact. The -externalized dependencies are based on dependency information in `package.json`, -which means it's important to keep it up to date. +`src/index.ts` as the entrypoint. All non-relative modules imports are considered +external, meaning the Rollup build will only compile the source code of the package +itself. All import statements of external dependencies, even within the same +monorepo, will stay intact. The build of the type definitions works quite differently. The entrypoint of the type definition build is the relative location of the package within the diff --git a/packages/cli/package.json b/packages/cli/package.json index af2c3afb2d..ec158fa5c1 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -103,7 +103,6 @@ "rollup": "^2.60.2", "rollup-plugin-dts": "^4.0.1", "rollup-plugin-esbuild": "^4.7.2", - "rollup-plugin-peer-deps-external": "^2.2.2", "rollup-plugin-postcss": "^4.0.0", "rollup-pluginutils": "^2.8.2", "run-script-webpack-plugin": "^0.0.11", diff --git a/packages/cli/src/lib/builder/config.test.ts b/packages/cli/src/lib/builder/config.test.ts new file mode 100644 index 0000000000..a2e99da73b --- /dev/null +++ b/packages/cli/src/lib/builder/config.test.ts @@ -0,0 +1,59 @@ +/* + * 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 { ExternalOption } from 'rollup'; +import { makeRollupConfigs } from './config'; +import { Output } from './types'; + +describe('makeRollupConfigs', () => { + it('should mark external modules correctly', async () => { + const importerPath = '/some/path.ts'; // when specified we don't care about the path + + const [config] = await makeRollupConfigs({ + outputs: new Set([Output.cjs]), + }); + const external = config.external as Exclude< + ExternalOption, + string | RegExp | (string | RegExp)[] + >; + + expect(external('foo', importerPath, false)).toBe(true); + expect(external('./foo', importerPath, false)).toBe(false); + expect(external('/foo', importerPath, false)).toBe(false); + expect(external('.\\foo', importerPath, false)).toBe(false); + expect(external('c:\\foo', importerPath, false)).toBe(false); + expect(external('@foo/bar', importerPath, false)).toBe(true); + expect(external('../foo', importerPath, false)).toBe(false); + + // Modules without an importer are entry points, i.e. not external + expect(external('foo', undefined, false)).toBe(false); + expect(external('./foo', undefined, false)).toBe(false); + expect(external('/foo', undefined, false)).toBe(false); + expect(external('.\\foo', undefined, false)).toBe(false); + expect(external('c:\\foo', undefined, false)).toBe(false); + expect(external('@foo/bar', undefined, false)).toBe(false); + expect(external('../foo', undefined, false)).toBe(false); + + // After modules have been resolved they're never marked as external + expect(external('foo', importerPath, true)).toBe(false); + expect(external('./foo', importerPath, true)).toBe(false); + expect(external('/foo', importerPath, true)).toBe(false); + expect(external('.\\foo', importerPath, true)).toBe(false); + expect(external('c:\\foo', importerPath, true)).toBe(false); + expect(external('@foo/bar', importerPath, true)).toBe(false); + expect(external('../foo', importerPath, true)).toBe(false); + }); +}); diff --git a/packages/cli/src/lib/builder/config.ts b/packages/cli/src/lib/builder/config.ts index 0a214f1a7a..fe91cedbb0 100644 --- a/packages/cli/src/lib/builder/config.ts +++ b/packages/cli/src/lib/builder/config.ts @@ -17,7 +17,6 @@ import chalk from 'chalk'; import fs from 'fs-extra'; import { relative as relativePath, resolve as resolvePath } from 'path'; -import peerDepsExternal from 'rollup-plugin-peer-deps-external'; import commonjs from '@rollup/plugin-commonjs'; import resolve from '@rollup/plugin-node-resolve'; import postcss from 'rollup-plugin-postcss'; @@ -33,6 +32,19 @@ import { BuildOptions, Output } from './types'; import { paths } from '../paths'; import { svgrTemplate } from '../svgrTemplate'; +function isFileImport(source: string) { + if (source.startsWith('.')) { + return true; + } + if (source.startsWith('/')) { + return true; + } + if (source.match(/[a-z]:/i)) { + return true; + } + return false; +} + export async function makeRollupConfigs( options: BuildOptions, ): Promise { @@ -81,12 +93,10 @@ export async function makeRollupConfigs( output, onwarn, preserveEntrySignatures: 'strict', - external: require('module').builtinModules, + // All module imports are always marked as external + external: (source, importer, isResolved) => + Boolean(importer && !isResolved && !isFileImport(source)), plugins: [ - peerDepsExternal({ - packageJsonPath: resolvePath(targetDir, 'package.json'), - includeDependencies: true, - }), resolve({ mainFields }), commonjs({ include: /node_modules/, diff --git a/yarn.lock b/yarn.lock index 5d8b1c24d7..02532c5286 100644 --- a/yarn.lock +++ b/yarn.lock @@ -22048,11 +22048,6 @@ rollup-plugin-esbuild@^4.7.2: joycon "^3.0.1" jsonc-parser "^3.0.0" -rollup-plugin-peer-deps-external@^2.2.2: - version "2.2.4" - resolved "https://registry.npmjs.org/rollup-plugin-peer-deps-external/-/rollup-plugin-peer-deps-external-2.2.4.tgz#8a420bbfd6dccc30aeb68c9bf57011f2f109570d" - integrity sha512-AWdukIM1+k5JDdAqV/Cxd+nejvno2FVLVeZ74NKggm3Q5s9cbbcOgUPGdbxPi4BXu7xGaZ8HG12F+thImYu/0g== - rollup-plugin-postcss@*, rollup-plugin-postcss@^4.0.0: version "4.0.2" resolved "https://registry.npmjs.org/rollup-plugin-postcss/-/rollup-plugin-postcss-4.0.2.tgz#15e9462f39475059b368ce0e49c800fa4b1f7050" From dd88d1e3ac7aa7a9c33d4e3009cab64a876727e1 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Fri, 4 Mar 2022 13:47:01 +0100 Subject: [PATCH 05/12] catalog-react: Remove `useEntityFromUrl` Signed-off-by: Johan Haals --- .changeset/late-pianos-attend.md | 5 +++ plugins/catalog-react/api-report.md | 3 -- plugins/catalog-react/src/hooks/index.ts | 1 - plugins/catalog-react/src/hooks/useEntity.tsx | 40 +------------------ 4 files changed, 6 insertions(+), 43 deletions(-) create mode 100644 .changeset/late-pianos-attend.md diff --git a/.changeset/late-pianos-attend.md b/.changeset/late-pianos-attend.md new file mode 100644 index 0000000000..e1e0aac392 --- /dev/null +++ b/.changeset/late-pianos-attend.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-react': minor +--- + +**BREAKING**: Removed `useEntityFromUrl`. diff --git a/plugins/catalog-react/api-report.md b/plugins/catalog-react/api-report.md index 40764b8844..f0d267d397 100644 --- a/plugins/catalog-react/api-report.md +++ b/plugins/catalog-react/api-report.md @@ -512,9 +512,6 @@ export function useEntity(): { refresh?: VoidFunction; }; -// @public @deprecated (undocumented) -export const useEntityFromUrl: () => EntityLoadingStatus; - // @public @deprecated export function useEntityKinds(): { error: Error | undefined; diff --git a/plugins/catalog-react/src/hooks/index.ts b/plugins/catalog-react/src/hooks/index.ts index e26f01928d..879ead8809 100644 --- a/plugins/catalog-react/src/hooks/index.ts +++ b/plugins/catalog-react/src/hooks/index.ts @@ -15,7 +15,6 @@ */ export { useEntity, - useEntityFromUrl, EntityProvider, AsyncEntityProvider, useAsyncEntity, diff --git a/plugins/catalog-react/src/hooks/useEntity.tsx b/plugins/catalog-react/src/hooks/useEntity.tsx index 152c1ebe61..75a623aaed 100644 --- a/plugins/catalog-react/src/hooks/useEntity.tsx +++ b/plugins/catalog-react/src/hooks/useEntity.tsx @@ -14,21 +14,12 @@ * limitations under the License. */ import { Entity } from '@backstage/catalog-model'; -import { - errorApiRef, - useApi, - useRouteRefParams, -} from '@backstage/core-plugin-api'; import { createVersionedContext, createVersionedValueMap, useVersionedContext, } from '@backstage/version-bridge'; -import React, { ReactNode, useEffect } from 'react'; -import { useNavigate } from 'react-router'; -import useAsyncRetry from 'react-use/lib/useAsyncRetry'; -import { catalogApiRef } from '../api'; -import { entityRouteRef } from '../routes'; +import React, { ReactNode } from 'react'; /** @public */ export type EntityLoadingStatus = { @@ -104,35 +95,6 @@ export const EntityProvider = ({ entity, children }: EntityProviderProps) => ( /> ); -/** @public - * @deprecated will be deleted shortly due to low external usage, re-implement if needed. - */ -export const useEntityFromUrl = (): EntityLoadingStatus => { - const { kind, namespace, name } = useRouteRefParams(entityRouteRef); - const navigate = useNavigate(); - const errorApi = useApi(errorApiRef); - const catalogApi = useApi(catalogApiRef); - - const { - value: entity, - error, - loading, - retry: refresh, - } = useAsyncRetry( - () => catalogApi.getEntityByRef({ kind, namespace, name }), - [catalogApi, kind, namespace, name], - ); - - useEffect(() => { - if (!name) { - errorApi.post(new Error('No name provided!')); - navigate('/'); - } - }, [errorApi, navigate, error, loading, entity, name]); - - return { entity, loading, error, refresh }; -}; - /** * Grab the current entity from the context, throws if the entity has not yet been loaded * or is not available. From f9c7bdd89994970edc1b8158073becbba2665135 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Fri, 4 Mar 2022 15:07:00 +0100 Subject: [PATCH 06/12] remove the last remnants of cookiecutter from scaffolder-backend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/brave-brooms-tie.md | 33 +++++++++++++++++++ .changeset/many-coins-drive.md | 8 +++++ packages/backend/src/plugins/scaffolder.ts | 7 ---- .../backend/src/plugins/scaffolder.ts | 6 ---- plugins/scaffolder-backend/api-report.md | 8 ----- plugins/scaffolder-backend/package.json | 1 - .../actions/builtin/createBuiltinActions.ts | 22 +------------ .../src/scaffolder/actions/builtin/index.ts | 3 -- .../src/service/router.test.ts | 2 -- .../scaffolder-backend/src/service/router.ts | 9 +---- 10 files changed, 43 insertions(+), 56 deletions(-) create mode 100644 .changeset/brave-brooms-tie.md create mode 100644 .changeset/many-coins-drive.md diff --git a/.changeset/brave-brooms-tie.md b/.changeset/brave-brooms-tie.md new file mode 100644 index 0000000000..a4b986c9d5 --- /dev/null +++ b/.changeset/brave-brooms-tie.md @@ -0,0 +1,33 @@ +--- +'@backstage/create-app': patch +--- + +Builtin support for cookiecutter based templates has been removed from `@backstage/plugin-scaffolder-backend`. Due to this, the `containerRunner` argument to its `createRouter` has also been removed. + +If you do not use cookiecutter templates and are fine with removing support from it in your own installation, update your `packages/backend/src/plugins/scaffolder.ts` file as follows: + +```diff +-import { DockerContainerRunner } from '@backstage/backend-common'; + import { CatalogClient } from '@backstage/catalog-client'; + import { createRouter } from '@backstage/plugin-scaffolder-backend'; +-import Docker from 'dockerode'; + import { Router } from 'express'; + import type { PluginEnvironment } from '../types'; + + export default async function createPlugin({ + reader, + discovery, + }: PluginEnvironment): Promise { +- const dockerClient = new Docker(); +- const containerRunner = new DockerContainerRunner({ dockerClient }); +- + const catalogClient = new CatalogClient({ discoveryApi: discovery }); +- + return await createRouter({ +- containerRunner, + logger, + config, + // ... +``` + +If you want to retain cookiecutter support, please use the `@backstage/plugin-scaffolder-backend-module-cookiecutter` package explicitly (see [its README](https://github.com/backstage/backstage/tree/master/plugins/scaffolder-backend-module-cookiecutter) for installation instructions). diff --git a/.changeset/many-coins-drive.md b/.changeset/many-coins-drive.md new file mode 100644 index 0000000000..b28a0b0519 --- /dev/null +++ b/.changeset/many-coins-drive.md @@ -0,0 +1,8 @@ +--- +'@backstage/plugin-scaffolder-backend': minor +--- + +**BREAKING**: + +- Removed the `createFetchCookiecutterAction` export, please use the `@backstage/plugin-scaffolder-backend-module-cookiecutter` package explicitly (see [its README](https://github.com/backstage/backstage/tree/master/plugins/scaffolder-backend-module-cookiecutter) for installation instructions). +- Removed the `containerRunner` argument from the types `RouterOptions` (as used by `createRouter`) and `CreateBuiltInActionsOptions` (as used by `createBuiltinActions`). diff --git a/packages/backend/src/plugins/scaffolder.ts b/packages/backend/src/plugins/scaffolder.ts index 619134a990..e0f3a4b1ca 100644 --- a/packages/backend/src/plugins/scaffolder.ts +++ b/packages/backend/src/plugins/scaffolder.ts @@ -14,10 +14,8 @@ * limitations under the License. */ -import { DockerContainerRunner } from '@backstage/backend-common'; import { CatalogClient } from '@backstage/catalog-client'; import { createRouter } from '@backstage/plugin-scaffolder-backend'; -import Docker from 'dockerode'; import { Router } from 'express'; import type { PluginEnvironment } from '../types'; @@ -28,13 +26,8 @@ export default async function createPlugin({ reader, discovery, }: PluginEnvironment): Promise { - const dockerClient = new Docker(); - const containerRunner = new DockerContainerRunner({ dockerClient }); - const catalogClient = new CatalogClient({ discoveryApi: discovery }); - return await createRouter({ - containerRunner, logger, config, database, diff --git a/packages/create-app/templates/default-app/packages/backend/src/plugins/scaffolder.ts b/packages/create-app/templates/default-app/packages/backend/src/plugins/scaffolder.ts index 6be2e9712d..a460fd8a6d 100644 --- a/packages/create-app/templates/default-app/packages/backend/src/plugins/scaffolder.ts +++ b/packages/create-app/templates/default-app/packages/backend/src/plugins/scaffolder.ts @@ -1,7 +1,5 @@ -import { DockerContainerRunner } from '@backstage/backend-common'; import { CatalogClient } from '@backstage/catalog-client'; import { createRouter } from '@backstage/plugin-scaffolder-backend'; -import Docker from 'dockerode'; import { Router } from 'express'; import type { PluginEnvironment } from '../types'; @@ -12,12 +10,8 @@ export default async function createPlugin({ reader, discovery, }: PluginEnvironment): Promise { - const dockerClient = new Docker(); - const containerRunner = new DockerContainerRunner({ dockerClient }); const catalogClient = new CatalogClient({ discoveryApi: discovery }); - return await createRouter({ - containerRunner, logger, config, database, diff --git a/plugins/scaffolder-backend/api-report.md b/plugins/scaffolder-backend/api-report.md index b18e199f40..a5e8ede8bb 100644 --- a/plugins/scaffolder-backend/api-report.md +++ b/plugins/scaffolder-backend/api-report.md @@ -9,8 +9,6 @@ import { CatalogApi } from '@backstage/catalog-client'; import { CatalogProcessor } from '@backstage/plugin-catalog-backend'; import { CatalogProcessorEmit } from '@backstage/plugin-catalog-backend'; import { Config } from '@backstage/config'; -import { ContainerRunner } from '@backstage/backend-common'; -import { createFetchCookiecutterAction } from '@backstage/plugin-scaffolder-backend-module-cookiecutter'; import { createPullRequest } from 'octokit-plugin-create-pull-request'; import { Entity } from '@backstage/catalog-model'; import express from 'express'; @@ -63,8 +61,6 @@ export interface CreateBuiltInActionsOptions { catalogClient: CatalogApi; // (undocumented) config: Config; - // @deprecated (undocumented) - containerRunner?: ContainerRunner; // (undocumented) integrations: ScmIntegrations; // (undocumented) @@ -99,8 +95,6 @@ export function createDebugLogAction(): TemplateAction<{ listWorkspace?: boolean | undefined; }>; -export { createFetchCookiecutterAction }; - // @public export function createFetchPlainAction(options: { reader: UrlReader; @@ -428,8 +422,6 @@ export interface RouterOptions { // (undocumented) config: Config; // (undocumented) - containerRunner?: ContainerRunner; - // (undocumented) database: PluginDatabaseManager; // (undocumented) logger: Logger_2; diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index 09df1818b4..f0822c27bb 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -42,7 +42,6 @@ "@backstage/integration": "^0.8.0", "@backstage/plugin-catalog-backend": "^0.23.0", "@backstage/plugin-scaffolder-common": "^0.2.3", - "@backstage/plugin-scaffolder-backend-module-cookiecutter": "^0.2.3", "@backstage/types": "^0.1.3", "@gitbeaker/core": "^34.6.0", "@gitbeaker/node": "^35.1.0", diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts index c03ba150c2..7405dc4de8 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { ContainerRunner, UrlReader } from '@backstage/backend-common'; +import { UrlReader } from '@backstage/backend-common'; import { JsonObject } from '@backstage/types'; import { CatalogApi } from '@backstage/catalog-client'; import { @@ -30,7 +30,6 @@ import { import { createDebugLogAction } from './debug'; import { createFetchPlainAction, createFetchTemplateAction } from './fetch'; -import { createFetchCookiecutterAction } from '@backstage/plugin-scaffolder-backend-module-cookiecutter'; import { createFilesystemDeleteAction, createFilesystemRenameAction, @@ -49,7 +48,6 @@ import { } from './github'; import { TemplateFilter } from '../../../lib'; import { TemplateAction } from '../types'; -import { getRootLogger } from '@backstage/backend-common'; /** * The options passed to {@link createBuiltinActions} @@ -59,8 +57,6 @@ export interface CreateBuiltInActionsOptions { reader: UrlReader; integrations: ScmIntegrations; catalogClient: CatalogApi; - /** @deprecated when the cookiecutter action is removed this won't be necessary */ - containerRunner?: ContainerRunner; config: Config; additionalTemplateFilters?: Record; } @@ -78,7 +74,6 @@ export const createBuiltinActions = ( const { reader, integrations, - containerRunner, catalogClient, config, additionalTemplateFilters, @@ -135,20 +130,5 @@ export const createBuiltinActions = ( }), ]; - if (containerRunner) { - getRootLogger().warn( - `[DEPRECATED] The fetch:cookiecutter action will be removed part of the default scaffolder actions in later versions. -You can install the package seperately and remove the containerRunner from the createBuiltInActions to remove this warning, -or you can migrate to using fetch:template https://backstage.io/docs/features/software-templates/builtin-actions#migrating-from-fetchcookiecutter-to-fetchtemplate`, - ); - actions.push( - createFetchCookiecutterAction({ - reader, - integrations, - containerRunner, - }), - ); - } - return actions as TemplateAction[]; }; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/index.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/index.ts index 8be1b62eaa..553481ba40 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/index.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/index.ts @@ -22,8 +22,5 @@ export * from './filesystem'; export * from './publish'; export * from './github'; -/** @deprecated please add this package to your own installation manually */ -export { createFetchCookiecutterAction } from '@backstage/plugin-scaffolder-backend-module-cookiecutter'; - export { runCommand, executeShellCommand } from './helpers'; export type { RunCommandOptions } from './helpers'; diff --git a/plugins/scaffolder-backend/src/service/router.test.ts b/plugins/scaffolder-backend/src/service/router.test.ts index 4041e41cf8..1c57153fb0 100644 --- a/plugins/scaffolder-backend/src/service/router.test.ts +++ b/plugins/scaffolder-backend/src/service/router.test.ts @@ -30,7 +30,6 @@ jest.doMock('fs-extra', () => ({ import { DatabaseManager, - DockerContainerRunner, getVoidLogger, PluginDatabaseManager, UrlReaders, @@ -122,7 +121,6 @@ describe('createRouter', () => { config: new ConfigReader({}), database: createDatabase(), catalogClient: createCatalogClient(template), - containerRunner: new DockerContainerRunner({} as any), reader: mockUrlReader, taskBroker, }); diff --git a/plugins/scaffolder-backend/src/service/router.ts b/plugins/scaffolder-backend/src/service/router.ts index 8f793a34d8..f7e375b0b2 100644 --- a/plugins/scaffolder-backend/src/service/router.ts +++ b/plugins/scaffolder-backend/src/service/router.ts @@ -14,11 +14,7 @@ * limitations under the License. */ -import { - ContainerRunner, - PluginDatabaseManager, - UrlReader, -} from '@backstage/backend-common'; +import { PluginDatabaseManager, UrlReader } from '@backstage/backend-common'; import { CatalogApi } from '@backstage/catalog-client'; import { parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model'; import { Entity } from '@backstage/catalog-model'; @@ -61,7 +57,6 @@ export interface RouterOptions { catalogClient: CatalogApi; actions?: TemplateAction[]; taskWorkers?: number; - containerRunner?: ContainerRunner; taskBroker?: TaskBroker; additionalTemplateFilters?: Record; } @@ -89,7 +84,6 @@ export async function createRouter( database, catalogClient, actions, - containerRunner, taskWorkers, additionalTemplateFilters, } = options; @@ -128,7 +122,6 @@ export async function createRouter( : createBuiltinActions({ integrations, catalogClient, - containerRunner, reader, config, additionalTemplateFilters, From 5afbd16d43df5771bbd44c6078a1a65e63831662 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Fri, 4 Mar 2022 15:40:33 +0100 Subject: [PATCH 07/12] remove octokit stuff from the scaffolder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/red-kiwis-divide.md | 5 + plugins/scaffolder-backend/api-report.md | 20 ---- .../builtin/github/OctokitProvider.test.ts | 88 -------------- .../actions/builtin/github/OctokitProvider.ts | 111 ------------------ .../actions/builtin/github/index.ts | 1 - 5 files changed, 5 insertions(+), 220 deletions(-) create mode 100644 .changeset/red-kiwis-divide.md delete mode 100644 plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/OctokitProvider.test.ts delete mode 100644 plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/OctokitProvider.ts diff --git a/.changeset/red-kiwis-divide.md b/.changeset/red-kiwis-divide.md new file mode 100644 index 0000000000..0bfb247093 --- /dev/null +++ b/.changeset/red-kiwis-divide.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': minor +--- + +**BREAKING**: Removed the previously deprecated `OctokitProvider` class. diff --git a/plugins/scaffolder-backend/api-report.md b/plugins/scaffolder-backend/api-report.md index b18e199f40..80a106bf27 100644 --- a/plugins/scaffolder-backend/api-report.md +++ b/plugins/scaffolder-backend/api-report.md @@ -21,7 +21,6 @@ import { Knex } from 'knex'; import { LocationSpec } from '@backstage/plugin-catalog-backend'; import { Logger as Logger_2 } from 'winston'; import { Observable } from '@backstage/types'; -import { Octokit } from 'octokit'; import { PluginDatabaseManager } from '@backstage/backend-common'; import { Schema } from 'jsonschema'; import { ScmIntegrationRegistry } from '@backstage/integration'; @@ -388,25 +387,6 @@ export function fetchContents({ outputPath: string; }): Promise; -// Warning: (ae-missing-release-tag) "OctokitProvider" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public @deprecated -export class OctokitProvider { - constructor( - integrations: ScmIntegrationRegistry, - githubCredentialsProvider?: GithubCredentialsProvider, - ); - // Warning: (ae-forgotten-export) The symbol "OctokitIntegration" needs to be exported by the entry point index.d.ts - // - // @deprecated - getOctokit( - repoUrl: string, - options?: { - token?: string; - }, - ): Promise; -} - // @public (undocumented) export interface OctokitWithPullRequestPluginClient { // (undocumented) diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/OctokitProvider.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/OctokitProvider.test.ts deleted file mode 100644 index e2449917ab..0000000000 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/OctokitProvider.test.ts +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { OctokitProvider } from './OctokitProvider'; -import { - ScmIntegrations, - DefaultGithubCredentialsProvider, -} from '@backstage/integration'; -import { ConfigReader } from '@backstage/config'; - -describe('getOctokit', () => { - const config = new ConfigReader({ - integrations: { - github: [ - { host: 'github.com', token: 'tokenlols' }, - { host: 'ghe.github.com' }, - ], - }, - }); - - const integrations = ScmIntegrations.fromConfig(config); - const githubCredentialsProvider = - DefaultGithubCredentialsProvider.fromIntegrations(integrations); - const octokitProvider = new OctokitProvider( - integrations, - githubCredentialsProvider, - ); - - beforeEach(() => { - jest.resetAllMocks(); - }); - - it('should throw an error when the repoUrl is not well formed', async () => { - await expect( - octokitProvider.getOctokit('github.com?repo=bob'), - ).rejects.toThrow(/missing owner/); - - await expect( - octokitProvider.getOctokit('github.com?owner=owner'), - ).rejects.toThrow(/missing repo/); - }); - - it('should throw if there is no integration config provided', async () => { - await expect( - octokitProvider.getOctokit('missing.com?repo=bob&owner=owner'), - ).rejects.toThrow(/No matching integration configuration/); - }); - - it('should throw if there is no token in the integration config that is returned', async () => { - await expect( - octokitProvider.getOctokit('ghe.github.com?repo=bob&owner=owner'), - ).rejects.toThrow(/No token available for host/); - }); - - it('should return proper Octokit', async () => { - const { client, token, owner, repo } = await octokitProvider.getOctokit( - 'github.com?repo=bob&owner=owner', - ); - expect(client).toBeDefined(); - expect(token).toBe('tokenlols'); - expect(owner).toBe('owner'); - expect(repo).toBe('bob'); - }); - - it('should return an octokit client with the passed in token if it is provided', async () => { - const { client, token, owner, repo } = await octokitProvider.getOctokit( - 'github.com?repo=bob&owner=owner', - { token: 'tokenlols2' }, - ); - expect(client).toBeDefined(); - expect(token).toBe('tokenlols2'); - expect(owner).toBe('owner'); - expect(repo).toBe('bob'); - }); -}); diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/OctokitProvider.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/OctokitProvider.ts deleted file mode 100644 index 2f3c43a6b8..0000000000 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/OctokitProvider.ts +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { InputError } from '@backstage/errors'; -import { - DefaultGithubCredentialsProvider, - GithubCredentialsProvider, - ScmIntegrationRegistry, -} from '@backstage/integration'; -import { Octokit } from 'octokit'; -import { parseRepoUrl } from '../publish/util'; - -export type OctokitIntegration = { - client: Octokit; - token: string; - owner: string; - repo: string; -}; -/** - * OctokitProvider provides Octokit client based on ScmIntegrationsRegistry configuration. - * OctokitProvider supports GitHub credentials caching out of the box. - * - * @deprecated we are no longer providing a way from the scaffolder to generate octokit instances. - * Implement your own if you're using this method from an external package, or use the internal `getOctokitOptions` function instead - */ -export class OctokitProvider { - private readonly integrations: ScmIntegrationRegistry; - private readonly githubCredentialsProvider: GithubCredentialsProvider; - - constructor( - integrations: ScmIntegrationRegistry, - githubCredentialsProvider?: GithubCredentialsProvider, - ) { - this.integrations = integrations; - this.githubCredentialsProvider = - githubCredentialsProvider || - DefaultGithubCredentialsProvider.fromIntegrations(this.integrations); - } - - /** - * gets standard Octokit client based on repository URL. - * - * @param repoUrl - Repository URL - * - * @deprecated we are no longer providing a way from the scaffolder to generate octokit instances. - * Implement your own if you're using this method from an external package, or use the internal `getOctokitOptions` function instead - */ - async getOctokit( - repoUrl: string, - options?: { token?: string }, - ): Promise { - const { owner, repo, host } = parseRepoUrl(repoUrl, this.integrations); - - if (!owner) { - throw new InputError(`No owner provided for repo ${repoUrl}`); - } - - const integrationConfig = this.integrations.github.byHost(host)?.config; - - if (!integrationConfig) { - throw new InputError(`No integration for host ${host}`); - } - - // Short circuit the internal Github Token provider the token provided - // by the action or the caller. - if (options?.token) { - const client = new Octokit({ - auth: options.token, - baseUrl: integrationConfig.apiBaseUrl, - previews: ['nebula-preview'], - }); - - return { client, token: options.token, owner, repo }; - } - - // TODO(blam): Consider changing this API to have owner, repoo interface instead of URL as the it's - // needless to create URL and then parse again the other side. - const { token } = await this.githubCredentialsProvider.getCredentials({ - url: `https://${host}/${encodeURIComponent(owner)}/${encodeURIComponent( - repo, - )}`, - }); - - if (!token) { - throw new InputError( - `No token available for host: ${host}, with owner ${owner}, and repo ${repo}`, - ); - } - - const client = new Octokit({ - auth: token, - baseUrl: integrationConfig.apiBaseUrl, - previews: ['nebula-preview'], - }); - - return { client, token, owner, repo }; - } -} diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/index.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/index.ts index 865c433c16..07614e8a03 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/index.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/index.ts @@ -16,4 +16,3 @@ export { createGithubActionsDispatchAction } from './githubActionsDispatch'; export { createGithubWebhookAction } from './githubWebhook'; -export { OctokitProvider } from './OctokitProvider'; From f3a7a9de6de729733a10e34b157aab0523567c00 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Fri, 4 Mar 2022 15:51:50 +0100 Subject: [PATCH 08/12] catalog-react: Remove useOwnedEntities hook Signed-off-by: Johan Haals --- .changeset/spotty-seals-press.md | 7 ++ .changeset/young-feet-flow.md | 5 ++ plugins/catalog-react/api-report.md | 16 ----- plugins/catalog-react/src/hooks/index.ts | 2 - .../src/hooks/useEntityTypeFilter.tsx | 11 --- .../src/hooks/useOwnedEntities.ts | 69 ------------------- .../OwnedEntityPicker/OwnedEntityPicker.tsx | 50 +++++++++++++- 7 files changed, 60 insertions(+), 100 deletions(-) create mode 100644 .changeset/spotty-seals-press.md create mode 100644 .changeset/young-feet-flow.md delete mode 100644 plugins/catalog-react/src/hooks/useOwnedEntities.ts diff --git a/.changeset/spotty-seals-press.md b/.changeset/spotty-seals-press.md new file mode 100644 index 0000000000..a0a69b2efc --- /dev/null +++ b/.changeset/spotty-seals-press.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-catalog-react': minor +--- + +**BREAKING**: Removed `useOwnedEntities` and moved its usage internally to the scaffolder-backend where it's used. + +**BREAKING**: Removed `EntityTypeReturn` type which is now inlined. diff --git a/.changeset/young-feet-flow.md b/.changeset/young-feet-flow.md new file mode 100644 index 0000000000..91e55da1d8 --- /dev/null +++ b/.changeset/young-feet-flow.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-react': patch +--- + +Internalized usage of `useOwnedEntities` hook. diff --git a/plugins/catalog-react/api-report.md b/plugins/catalog-react/api-report.md index 40764b8844..0ace24142b 100644 --- a/plugins/catalog-react/api-report.md +++ b/plugins/catalog-react/api-report.md @@ -13,7 +13,6 @@ import { ComponentEntity } from '@backstage/catalog-model'; import { ComponentProps } from 'react'; import { CompoundEntityRef } from '@backstage/catalog-model'; import { Entity } from '@backstage/catalog-model'; -import { GetEntitiesResponse } from '@backstage/catalog-client'; import { IconButton } from '@material-ui/core'; import { LinkProps } from '@backstage/core-components'; import { Observable } from '@backstage/types'; @@ -388,15 +387,6 @@ export interface EntityTypePickerProps { initialFilter?: string; } -// @public @deprecated (undocumented) -export type EntityTypeReturn = { - loading: boolean; - error?: Error; - availableTypes: string[]; - selectedTypes: string[]; - setSelectedTypes: (types: string[]) => void; -}; - // @public export const FavoriteEntity: (props: FavoriteEntityProps) => JSX.Element; @@ -549,12 +539,6 @@ export function useEntityTypeFilter(): { setSelectedTypes: (types: string[]) => void; }; -// @public @deprecated -export function useOwnedEntities(allowedKinds?: string[]): { - loading: boolean; - ownedEntities: GetEntitiesResponse | undefined; -}; - // @public @deprecated export function useOwnUser(): AsyncState; diff --git a/plugins/catalog-react/src/hooks/index.ts b/plugins/catalog-react/src/hooks/index.ts index e26f01928d..9e2830a89c 100644 --- a/plugins/catalog-react/src/hooks/index.ts +++ b/plugins/catalog-react/src/hooks/index.ts @@ -35,12 +35,10 @@ export type { EntityListContextProps, } from './useEntityListProvider'; export { useEntityTypeFilter } from './useEntityTypeFilter'; -export type { EntityTypeReturn } from './useEntityTypeFilter'; export { useEntityKinds } from './useEntityKinds'; export { useOwnUser } from './useOwnUser'; export { useRelatedEntities } from './useRelatedEntities'; export { useStarredEntities } from './useStarredEntities'; export { useStarredEntity } from './useStarredEntity'; export { loadCatalogOwnerRefs, useEntityOwnership } from './useEntityOwnership'; -export { useOwnedEntities } from './useOwnedEntities'; export { useEntityPermission } from './useEntityPermission'; diff --git a/plugins/catalog-react/src/hooks/useEntityTypeFilter.tsx b/plugins/catalog-react/src/hooks/useEntityTypeFilter.tsx index 2159c30edc..9971536138 100644 --- a/plugins/catalog-react/src/hooks/useEntityTypeFilter.tsx +++ b/plugins/catalog-react/src/hooks/useEntityTypeFilter.tsx @@ -23,17 +23,6 @@ import { catalogApiRef } from '../api'; import { useEntityList } from './useEntityListProvider'; import { EntityTypeFilter } from '../filters'; -/** @public - * @deprecated type inlined with {@link useEntityTypeFilter}. - */ -export type EntityTypeReturn = { - loading: boolean; - error?: Error; - availableTypes: string[]; - selectedTypes: string[]; - setSelectedTypes: (types: string[]) => void; -}; - /** * A hook built on top of `useEntityList` for enabling selection of valid `spec.type` values * based on the selected EntityKindFilter. diff --git a/plugins/catalog-react/src/hooks/useOwnedEntities.ts b/plugins/catalog-react/src/hooks/useOwnedEntities.ts deleted file mode 100644 index a2258cf138..0000000000 --- a/plugins/catalog-react/src/hooks/useOwnedEntities.ts +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { catalogApiRef } from './../api'; -import { loadCatalogOwnerRefs } from './useEntityOwnership'; -import { identityApiRef, useApi } from '@backstage/core-plugin-api'; -import { RELATION_OWNED_BY } from '@backstage/catalog-model'; -import { GetEntitiesResponse } from '@backstage/catalog-client'; -import useAsync from 'react-use/lib/useAsync'; -import { useMemo } from 'react'; - -/** - * Takes the relevant parts of the Backstage identity, and translates them into - * a list of entities which are owned by the user. Takes an optional parameter - * to filter the entities based on allowedKinds - * - * @public - * - * @param allowedKinds - Array of allowed kinds to filter the entities - * @deprecated Use `ownershipEntityRefs` from `identityApi.getBackstageIdentity()` instead. - */ -export function useOwnedEntities(allowedKinds?: string[]): { - loading: boolean; - ownedEntities: GetEntitiesResponse | undefined; -} { - const identityApi = useApi(identityApiRef); - const catalogApi = useApi(catalogApiRef); - - const { loading, value: refs } = useAsync(async () => { - const identity = await identityApi.getBackstageIdentity(); - const identityRefs = identity.ownershipEntityRefs; - const catalogRefs = await loadCatalogOwnerRefs(catalogApi, identityRefs); - const catalogs = await catalogApi.getEntities( - allowedKinds - ? { - filter: { - kind: allowedKinds, - [`relations.${RELATION_OWNED_BY}`]: - [...identityRefs, ...catalogRefs] || [], - }, - } - : { - filter: { - [`relations.${RELATION_OWNED_BY}`]: - [...identityRefs, ...catalogRefs] || [], - }, - }, - ); - return catalogs; - }, []); - - const ownedEntities = useMemo(() => { - return refs; - }, [refs]); - - return useMemo(() => ({ loading, ownedEntities }), [loading, ownedEntities]); -} diff --git a/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx index aded9acffa..fb4a7a7234 100644 --- a/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx +++ b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx @@ -13,14 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { GetEntitiesResponse } from '@backstage/catalog-client'; +import { RELATION_OWNED_BY } from '@backstage/catalog-model'; +import { identityApiRef, useApi } from '@backstage/core-plugin-api'; import { + catalogApiRef, humanizeEntityRef, - useOwnedEntities, } from '@backstage/plugin-catalog-react'; import { TextField } from '@material-ui/core'; import FormControl from '@material-ui/core/FormControl'; import Autocomplete from '@material-ui/lab/Autocomplete'; -import React from 'react'; +import React, { useMemo } from 'react'; +import useAsync from 'react-use/lib/useAsync'; import { FieldExtensionComponentProps } from '../../../extensions'; @@ -86,3 +90,45 @@ export const OwnedEntityPicker = ( ); }; + +/** + * Takes the relevant parts of the Backstage identity, and translates them into + * a list of entities which are owned by the user. Takes an optional parameter + * to filter the entities based on allowedKinds + * + * + * @param allowedKinds - Array of allowed kinds to filter the entities + */ +function useOwnedEntities(allowedKinds?: string[]): { + loading: boolean; + ownedEntities: GetEntitiesResponse | undefined; +} { + const identityApi = useApi(identityApiRef); + const catalogApi = useApi(catalogApiRef); + + const { loading, value: refs } = useAsync(async () => { + const identity = await identityApi.getBackstageIdentity(); + const identityRefs = identity.ownershipEntityRefs; + const catalogs = await catalogApi.getEntities( + allowedKinds + ? { + filter: { + kind: allowedKinds, + [`relations.${RELATION_OWNED_BY}`]: identityRefs || [], + }, + } + : { + filter: { + [`relations.${RELATION_OWNED_BY}`]: identityRefs || [], + }, + }, + ); + return catalogs; + }, []); + + const ownedEntities = useMemo(() => { + return refs; + }, [refs]); + + return useMemo(() => ({ loading, ownedEntities }), [loading, ownedEntities]); +} From 07400fd84bb094c5cc5779b933e96b9917e26213 Mon Sep 17 00:00:00 2001 From: Andrew Shirley Date: Fri, 4 Mar 2022 15:29:44 +0000 Subject: [PATCH 09/12] Correct log message Signed-off-by: Andrew Shirley --- .../src/processing/ProcessorOutputCollector.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/catalog-backend/src/processing/ProcessorOutputCollector.ts b/plugins/catalog-backend/src/processing/ProcessorOutputCollector.ts index c3cc6e288b..0a11f7191d 100644 --- a/plugins/catalog-backend/src/processing/ProcessorOutputCollector.ts +++ b/plugins/catalog-backend/src/processing/ProcessorOutputCollector.ts @@ -72,17 +72,17 @@ export class ProcessorOutputCollector { if (i.type === 'entity') { let entity: Entity; + const location = stringifyLocationRef(i.location); + try { entity = validateEntityEnvelope(i.entity); } catch (e) { assertError(e); - this.logger.debug(`Envelope validation failed at ${i.location}, ${e}`); + this.logger.debug(`Envelope validation failed at ${location}, ${e}`); this.errors.push(e); return; } - const location = stringifyLocationRef(i.location); - // Note that at this point, we have only validated the envelope part of // the entity data. Annotations are not part of that, so we have to be // defensive. If the annotations were malformed (e.g. were not a valid From 51a9f8f1228e849bc599b791ca8c35ac5d9bbd1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Fri, 4 Mar 2022 16:37:21 +0100 Subject: [PATCH 10/12] more cleanup in catalog-model MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/modern-windows-brush.md | 9 + packages/catalog-model/api-report.md | 31 ---- packages/catalog-model/src/entity/index.ts | 1 - packages/catalog-model/src/entity/ref.test.ts | 164 +----------------- packages/catalog-model/src/entity/ref.ts | 39 ----- packages/catalog-model/src/index.ts | 2 +- .../catalog-model/src/location/annotation.ts | 18 +- packages/catalog-model/src/location/index.ts | 1 - packages/catalog-model/src/location/types.ts | 33 ---- packages/catalog-model/src/types.ts | 22 --- 10 files changed, 23 insertions(+), 297 deletions(-) create mode 100644 .changeset/modern-windows-brush.md delete mode 100644 packages/catalog-model/src/location/types.ts diff --git a/.changeset/modern-windows-brush.md b/.changeset/modern-windows-brush.md new file mode 100644 index 0000000000..49c45eb41e --- /dev/null +++ b/.changeset/modern-windows-brush.md @@ -0,0 +1,9 @@ +--- +'@backstage/catalog-model': minor +--- + +**BREAKING**: + +- Removed the previously deprecated type `EntityRef`. Please use `string` for stringified entity refs, `CompoundEntityRef` for compound kind-namespace-name triplet objects, or custom objects like `{ kind?: string; namespace?: string; name: string }` and similar if you have need for partial types. +- Removed the previously deprecated type `LocationSpec` type, which has been moved to `@backstage/plugin-catalog-backend`. +- Removed the previously deprecated function `parseEntityName`. Please use `parseEntityRef` instead. diff --git a/packages/catalog-model/api-report.md b/packages/catalog-model/api-report.md index 9a65401d55..90242f9293 100644 --- a/packages/catalog-model/api-report.md +++ b/packages/catalog-model/api-report.md @@ -190,15 +190,6 @@ export type EntityPolicy = { enforce(entity: Entity): Promise; }; -// @public @deprecated -export type EntityRef = - | string - | { - kind?: string; - namespace?: string; - name: string; - }; - // @public export type EntityRelation = { type: string; @@ -316,13 +307,6 @@ export { LocationEntityV1alpha1 }; // @public export const locationEntityV1alpha1Validator: KindValidator; -// @public @deprecated -export type LocationSpec = { - type: string; - target: string; - presence?: 'optional' | 'required'; -}; - // @public export function makeValidator(overrides?: Partial): Validators; @@ -333,21 +317,6 @@ export class NoForeignRootFieldsEntityPolicy implements EntityPolicy { enforce(entity: Entity): Promise; } -// @public @deprecated -export function parseEntityName( - ref: - | string - | { - kind?: string; - namespace?: string; - name: string; - }, - context?: { - defaultKind?: string; - defaultNamespace?: string; - }, -): CompoundEntityRef; - // @public export function parseEntityRef( ref: diff --git a/packages/catalog-model/src/entity/index.ts b/packages/catalog-model/src/entity/index.ts index fb9eee0353..f46f53945f 100644 --- a/packages/catalog-model/src/entity/index.ts +++ b/packages/catalog-model/src/entity/index.ts @@ -36,7 +36,6 @@ export * from './policies'; export { getCompoundEntityRef, getEntityName, - parseEntityName, parseEntityRef, stringifyEntityRef, } from './ref'; diff --git a/packages/catalog-model/src/entity/ref.test.ts b/packages/catalog-model/src/entity/ref.test.ts index 045c4710dc..6cb7612439 100644 --- a/packages/catalog-model/src/entity/ref.test.ts +++ b/packages/catalog-model/src/entity/ref.test.ts @@ -14,171 +14,9 @@ * limitations under the License. */ -import { DEFAULT_NAMESPACE } from './constants'; -import { parseEntityName, parseEntityRef } from './ref'; +import { parseEntityRef } from './ref'; describe('ref', () => { - describe('parseEntityName', () => { - it('handles some omissions', () => { - expect(parseEntityName('a:b/c')).toEqual({ - kind: 'a', - namespace: 'b', - name: 'c', - }); - expect(() => parseEntityName('b/c')).toThrow(/kind/); - expect(parseEntityName('a:c')).toEqual({ - kind: 'a', - namespace: DEFAULT_NAMESPACE, - name: 'c', - }); - expect(() => parseEntityName('c')).toThrow(/kind/); - }); - - it('rejects bad inputs', () => { - expect(() => parseEntityName(null as any)).toThrow(); - expect(() => parseEntityName(7 as any)).toThrow(); - expect(() => parseEntityName('a:b:c')).toThrow(); - expect(() => parseEntityName('a/b/c')).toThrow(); - expect(() => parseEntityName('a/b:c')).toThrow(); - expect(() => parseEntityName('a:b/c/d')).toThrow(); - expect(() => parseEntityName('a:b/c:d')).toThrow(); - }); - - it('rejects empty parts in strings', () => { - // one is empty - expect(() => parseEntityName(':b/c')).toThrow(); - expect(() => parseEntityName('a:/c')).toThrow(); - expect(() => parseEntityName('a:b/')).toThrow(); - // two are empty - expect(() => parseEntityName('a:/')).toThrow(); - expect(() => parseEntityName(':b/')).toThrow(); - expect(() => parseEntityName(':/c')).toThrow(); - // three are empty - expect(() => parseEntityName(':/')).toThrow(); - // one is left out, one empty - expect(() => parseEntityName('/c')).toThrow(); - expect(() => parseEntityName('b/')).toThrow(); - expect(() => parseEntityName(':c')).toThrow(); - expect(() => parseEntityName('a:')).toThrow(); - // nothing at all - expect(() => parseEntityName('')).toThrow(); - }); - - it('rejects empty parts in compounds', () => { - // one is empty - expect(() => - parseEntityName({ kind: '', namespace: 'b', name: 'c' }), - ).toThrow(); - expect(() => parseEntityName({ namespace: 'b', name: 'c' })).toThrow(); - expect(() => - parseEntityName({ kind: 'a', namespace: '', name: 'c' }), - ).toThrow(); - expect(() => parseEntityName({ kind: 'a', name: 'c' })).not.toThrow(); - expect(() => - parseEntityName({ kind: 'a', namespace: 'b', name: '' }), - ).toThrow(); - expect(() => - parseEntityName({ kind: 'a', namespace: 'b' } as any), - ).toThrow(); - // two are empty - expect(() => - parseEntityName({ kind: '', namespace: '', name: 'c' }), - ).toThrow(); - expect(() => parseEntityName({ name: 'c' })).toThrow(); - expect(() => - parseEntityName({ kind: '', namespace: 'b', name: '' }), - ).toThrow(); - expect(() => parseEntityName({ namespace: 'b' } as any)).toThrow(); - expect(() => - parseEntityName({ kind: 'a', namespace: '', name: '' }), - ).toThrow(); - expect(() => parseEntityName({ kind: 'a' } as any)).toThrow(); - // three are empty - expect(() => - parseEntityName({ kind: '', namespace: '', name: '' }), - ).toThrow(); - expect(() => parseEntityName({} as any)).toThrow(); - // one is left out, one empty - expect(() => parseEntityName({ namespace: '', name: 'c' })).toThrow(); - expect(() => parseEntityName({ namespace: 'b', name: '' })).toThrow(); - expect(() => parseEntityName({ kind: '', name: 'c' })).toThrow(); - expect(() => parseEntityName({ kind: 'a', name: '' })).toThrow(); - }); - - it('adds defaults where necessary to strings', () => { - expect( - parseEntityName('a:b/c', { defaultKind: 'x', defaultNamespace: 'y' }), - ).toEqual({ kind: 'a', namespace: 'b', name: 'c' }); - expect( - parseEntityName('b/c', { defaultKind: 'x', defaultNamespace: 'y' }), - ).toEqual({ kind: 'x', namespace: 'b', name: 'c' }); - expect( - parseEntityName('a:c', { defaultKind: 'x', defaultNamespace: 'y' }), - ).toEqual({ kind: 'a', namespace: 'y', name: 'c' }); - expect(parseEntityName('a:c', { defaultKind: 'x' })).toEqual({ - kind: 'a', - namespace: DEFAULT_NAMESPACE, - name: 'c', - }); - expect( - parseEntityName('c', { defaultKind: 'x', defaultNamespace: 'y' }), - ).toEqual({ kind: 'x', namespace: 'y', name: 'c' }); - expect(parseEntityName('c', { defaultKind: 'x' })).toEqual({ - kind: 'x', - namespace: DEFAULT_NAMESPACE, - name: 'c', - }); - }); - - it('adds defaults where necessary to compounds', () => { - expect( - parseEntityName( - { kind: 'a', namespace: 'b', name: 'c' }, - { defaultKind: 'x', defaultNamespace: 'y' }, - ), - ).toEqual({ kind: 'a', namespace: 'b', name: 'c' }); - expect( - parseEntityName( - { namespace: 'b', name: 'c' }, - { defaultKind: 'x', defaultNamespace: 'y' }, - ), - ).toEqual({ kind: 'x', namespace: 'b', name: 'c' }); - expect( - parseEntityName( - { kind: 'a', name: 'c' }, - { defaultKind: 'x', defaultNamespace: 'y' }, - ), - ).toEqual({ kind: 'a', namespace: 'y', name: 'c' }); - expect( - parseEntityName({ kind: 'a', name: 'c' }, { defaultKind: 'x' }), - ).toEqual({ kind: 'a', namespace: DEFAULT_NAMESPACE, name: 'c' }); - expect( - parseEntityName( - { name: 'c' }, - { defaultKind: 'x', defaultNamespace: 'y' }, - ), - ).toEqual({ kind: 'x', namespace: 'y', name: 'c' }); - expect(parseEntityName({ name: 'c' }, { defaultKind: 'x' })).toEqual({ - kind: 'x', - namespace: DEFAULT_NAMESPACE, - name: 'c', - }); - // empty strings are errors, not defaults - expect(() => - parseEntityName( - { kind: '', namespace: 'b', name: 'c' }, - { defaultKind: 'x', defaultNamespace: 'y' }, - ), - ).toThrow(/kind/); - expect(() => - parseEntityName( - { kind: 'a', namespace: '', name: 'c' }, - { defaultKind: 'x', defaultNamespace: 'y' }, - ), - ).toThrow(/namespace/); - }); - }); - describe('parseEntityRef', () => { it('handles some omissions', () => { expect(parseEntityRef('a:b/c')).toEqual({ diff --git a/packages/catalog-model/src/entity/ref.ts b/packages/catalog-model/src/entity/ref.ts index 4529b1174c..acede5a56b 100644 --- a/packages/catalog-model/src/entity/ref.ts +++ b/packages/catalog-model/src/entity/ref.ts @@ -64,45 +64,6 @@ export function getCompoundEntityRef(entity: Entity): CompoundEntityRef { }; } -/** - * Parses an entity reference, either on string or compound form, and always - * returns a complete entity name including kind, namespace and name. - * - * @remarks - * - * This function automatically assumes the default namespace "default" unless - * otherwise specified as part of the options, and will throw an error if no - * kind was specified in the input reference and no default kind was given. - * - * @deprecated Please use parseEntityRef instead - * @public - * @param ref - The reference to parse - * @param context - The context of defaults that the parsing happens within - * @returns A complete entity name - */ -export function parseEntityName( - ref: string | { kind?: string; namespace?: string; name: string }, - context: { - /** The default kind, if none is given in the reference */ - defaultKind?: string; - /** The default namespace, if none is given in the reference */ - defaultNamespace?: string; - } = {}, -): CompoundEntityRef { - const { kind, namespace, name } = parseEntityRef(ref, { - defaultNamespace: DEFAULT_NAMESPACE, - ...context, - }); - - if (!kind) { - throw new Error( - `Entity reference ${namespace}/${name} did not contain a kind`, - ); - } - - return { kind, namespace, name }; -} - /** * Parses an entity reference, either on string or compound form, and returns * a structure with a name, and optional kind and namespace. diff --git a/packages/catalog-model/src/index.ts b/packages/catalog-model/src/index.ts index 19eacd4925..b5ccfed149 100644 --- a/packages/catalog-model/src/index.ts +++ b/packages/catalog-model/src/index.ts @@ -24,5 +24,5 @@ export * from './entity'; export { EntityPolicies } from './EntityPolicies'; export * from './kinds'; export * from './location'; -export type { EntityName, EntityRef, CompoundEntityRef } from './types'; +export type { EntityName, CompoundEntityRef } from './types'; export * from './validation'; diff --git a/packages/catalog-model/src/location/annotation.ts b/packages/catalog-model/src/location/annotation.ts index 61dbc0b305..bd282e2871 100644 --- a/packages/catalog-model/src/location/annotation.ts +++ b/packages/catalog-model/src/location/annotation.ts @@ -15,19 +15,25 @@ */ /** - * Constant storing location annotation. + * Entity annotation containing the location from which the entity is sourced. * - * @public */ + * @public + */ export const ANNOTATION_LOCATION = 'backstage.io/managed-by-location'; + /** - * Constant storing origin location annotation + * Entity annotation containing the originally sourced location which ultimately + * led to this entity being ingested. * - * @public */ + * @public + */ export const ANNOTATION_ORIGIN_LOCATION = 'backstage.io/managed-by-origin-location'; /** - * Contant storing source location annotation + * Entity annotation pointing to the source (e.g. source code repository root or + * similar) for this entity. * - * @public */ + * @public + */ export const ANNOTATION_SOURCE_LOCATION = 'backstage.io/source-location'; diff --git a/packages/catalog-model/src/location/index.ts b/packages/catalog-model/src/location/index.ts index dc709144b2..c53a1d2c83 100644 --- a/packages/catalog-model/src/location/index.ts +++ b/packages/catalog-model/src/location/index.ts @@ -24,4 +24,3 @@ export { parseLocationRef, stringifyLocationRef, } from './helpers'; -export type { LocationSpec } from './types'; diff --git a/packages/catalog-model/src/location/types.ts b/packages/catalog-model/src/location/types.ts deleted file mode 100644 index 9e2c9339e6..0000000000 --- a/packages/catalog-model/src/location/types.ts +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Holds the entity location information. - * - * @remarks - * - * `presence` flag: when using repo importer plugin, location is being created before the component yaml file is merged to the main branch. - * This flag is then set to indicate that the file can be not present. - * default value: 'required'. - * - * @public - * @deprecated Import from `@backstage/plugin-catalog-backend` instead. - */ -export type LocationSpec = { - type: string; - target: string; - presence?: 'optional' | 'required'; -}; diff --git a/packages/catalog-model/src/types.ts b/packages/catalog-model/src/types.ts index e7d819ace9..7b3f23c64f 100644 --- a/packages/catalog-model/src/types.ts +++ b/packages/catalog-model/src/types.ts @@ -33,25 +33,3 @@ export type CompoundEntityRef = { * @public */ export type EntityName = CompoundEntityRef; - -/** - * A reference by name to an entity, either as a compact string representation, - * or as a compound reference structure. - * - * @deprecated Please use string directly, or EntityName (depending on what you actually need) - * @remarks - * - * The string representation is on the form `[:][/]`. - * - * Left-out parts of the reference need to be handled by the application, - * either by rejecting the reference or by falling back to default values. - * - * @public - */ -export type EntityRef = - | string - | { - kind?: string; - namespace?: string; - name: string; - }; From ed027b8b280db54697bd37cd2e592de1f067e370 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Fri, 4 Mar 2022 16:59:57 +0100 Subject: [PATCH 11/12] just fix some random ugly comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .../DependencyGraph/DependencyGraph.tsx | 2 +- .../test-utils/src/testUtils/logCollector.ts | 26 ++++++++++------ .../catalog-backend/src/ingestion/types.ts | 2 +- .../catalog-backend/src/processing/types.ts | 4 +-- plugins/catalog-backend/src/service/types.ts | 3 +- .../src/scaffolder/actions/types.ts | 3 +- plugins/tech-insights-node/src/facts.ts | 30 ++++++++----------- .../techdocs-backend/src/service/router.ts | 4 +-- 8 files changed, 40 insertions(+), 34 deletions(-) diff --git a/packages/core-components/src/components/DependencyGraph/DependencyGraph.tsx b/packages/core-components/src/components/DependencyGraph/DependencyGraph.tsx index 49f209d04e..6db8e2dd02 100644 --- a/packages/core-components/src/components/DependencyGraph/DependencyGraph.tsx +++ b/packages/core-components/src/components/DependencyGraph/DependencyGraph.tsx @@ -99,7 +99,7 @@ export interface DependencyGraphProps /** * Margin on top and bottom of whole graph * - * @remarks + * @remarks * * Default: 0 */ diff --git a/packages/test-utils/src/testUtils/logCollector.ts b/packages/test-utils/src/testUtils/logCollector.ts index b9fa6220ed..7529a00e7a 100644 --- a/packages/test-utils/src/testUtils/logCollector.ts +++ b/packages/test-utils/src/testUtils/logCollector.ts @@ -18,37 +18,44 @@ /** * Severity levels of {@link CollectedLogs} - * @public */ + * @public + */ export type LogFuncs = 'log' | 'warn' | 'error'; /** * AsyncLogCollector type used in {@link (withLogCollector:1)} callback function. - * @public */ + * @public + */ export type AsyncLogCollector = () => Promise; /** * SyncLogCollector type used in {@link (withLogCollector:2)} callback function. - * @public */ + * @public + */ export type SyncLogCollector = () => void; /** * Union type used in {@link (withLogCollector:3)} callback function. - * @public */ + * @public + */ export type LogCollector = AsyncLogCollector | SyncLogCollector; /** * Map of severity level and corresponding log lines. - * @public */ + * @public + */ export type CollectedLogs = { [key in T]: string[] }; const allCategories = ['log', 'warn', 'error']; /** * Asynchronous log collector with that collects all categories - * @public */ + * @public + */ export function withLogCollector( callback: AsyncLogCollector, ): Promise>; /** * Synchronous log collector with that collects all categories - * @public */ + * @public + */ export function withLogCollector( callback: SyncLogCollector, ): CollectedLogs; @@ -64,7 +71,8 @@ export function withLogCollector( /** * Synchronous log collector with that only collects selected categories - * @public */ + * @public + */ export function withLogCollector( logsToCollect: T[], callback: SyncLogCollector, @@ -73,7 +81,7 @@ export function withLogCollector( /** * Log collector that collect logs either from a sync or async collector. * @public - * */ + */ export function withLogCollector( logsToCollect: LogFuncs[] | LogCollector, callback?: LogCollector, diff --git a/plugins/catalog-backend/src/ingestion/types.ts b/plugins/catalog-backend/src/ingestion/types.ts index 37d12d12b1..6d1e9a3927 100644 --- a/plugins/catalog-backend/src/ingestion/types.ts +++ b/plugins/catalog-backend/src/ingestion/types.ts @@ -62,7 +62,7 @@ export type AnalyzeLocationExistingEntity = { * enough info for the frontend to know what form data to show to the user * for overriding/completing the info. * @public - * */ + */ export type AnalyzeLocationGenerateEntity = { // Some form of partial representation of the entity entity: RecursivePartial; diff --git a/plugins/catalog-backend/src/processing/types.ts b/plugins/catalog-backend/src/processing/types.ts index 484cd73939..b178522c14 100644 --- a/plugins/catalog-backend/src/processing/types.ts +++ b/plugins/catalog-backend/src/processing/types.ts @@ -48,7 +48,7 @@ export type EntityProcessingResult = /** * Responsible for executing the individual processing steps in order to fully process an entity. * @public - * */ + */ export interface CatalogProcessingOrchestrator { process(request: EntityProcessingRequest): Promise; } @@ -56,7 +56,7 @@ export interface CatalogProcessingOrchestrator { /** * Entities that are not yet processed. * @public - * */ + */ export type DeferredEntity = { entity: Entity; locationKey?: string; diff --git a/plugins/catalog-backend/src/service/types.ts b/plugins/catalog-backend/src/service/types.ts index 02268ab63c..fc315b9d89 100644 --- a/plugins/catalog-backend/src/service/types.ts +++ b/plugins/catalog-backend/src/service/types.ts @@ -77,7 +77,8 @@ export interface RefreshService { /** * Interacts with the database to manage locations. - * @public */ + * @public + */ export interface LocationStore { createLocation(location: LocationInput): Promise; listLocations(): Promise; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/types.ts b/plugins/scaffolder-backend/src/scaffolder/actions/types.ts index 2a87f58fd8..55ef68423e 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/types.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/types.ts @@ -26,7 +26,8 @@ import { /** * ActionContext is passed into scaffolder actions. - * @public */ + * @public + */ export type ActionContext = { /** * Base URL for the location of the task spec, typically the url of the source entity file. diff --git a/plugins/tech-insights-node/src/facts.ts b/plugins/tech-insights-node/src/facts.ts index 7a70f92f92..24b6764ba4 100644 --- a/plugins/tech-insights-node/src/facts.ts +++ b/plugins/tech-insights-node/src/facts.ts @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { DateTime, DurationLike } from 'luxon'; import { Config } from '@backstage/config'; import { PluginEndpointDiscovery } from '@backstage/backend-common'; @@ -62,11 +63,10 @@ export type TechInsightFact = { }; /** - * Response type used when returning from database and API. * Adds a field for ref for easier usage * - * @public + * @public */ export type FlatTechInsightFact = TechInsightFact & { /** @@ -76,12 +76,12 @@ export type FlatTechInsightFact = TechInsightFact & { }; /** - * @public - * * A record type to specify individual fact shapes * * Used as part of a schema to validate, identify and generically construct usage implementations * of individual fact values in the system. + * + * @public */ export type FactSchema = { /** @@ -142,11 +142,9 @@ export type FactRetrieverContext = { }; /** - * @public - * * FactRetriever interface * - * A component specifying + * @public */ export interface FactRetriever { /** @@ -191,10 +189,9 @@ export interface FactRetriever { } /** - * @public - * * A Luxon duration like object for time to live value * + * @public * @example * \{ timeToLive: 1209600000 \} * \{ timeToLive: \{ weeks: 4 \} \} @@ -203,10 +200,9 @@ export interface FactRetriever { export type TTL = { timeToLive: DurationLike }; /** - * @public - * * A maximum number for items to be kept in the database for each fact retriever/entity pair * + * @public * @example * \{ maxItems: 10 \} * @@ -214,25 +210,25 @@ export type TTL = { timeToLive: DurationLike }; export type MaxItems = { maxItems: number }; /** - * @public - * * A fact lifecycle definition. Determines which strategy to use to purge expired facts from the database. + * + * @public */ export type FactLifecycle = TTL | MaxItems; /** - * @public - * * A flat serializable structure for Facts. * Containing information about fact schema, version, id, and entity filters + * + * @public */ export type FactSchemaDefinition = Omit; /** - * @public - * * Registration of a fact retriever * Used to add and schedule individual fact retrievers to the fact retriever engine. + * + * @public */ export type FactRetrieverRegistration = { /** diff --git a/plugins/techdocs-backend/src/service/router.ts b/plugins/techdocs-backend/src/service/router.ts index 73f212d049..9d240cb7fa 100644 --- a/plugins/techdocs-backend/src/service/router.ts +++ b/plugins/techdocs-backend/src/service/router.ts @@ -347,8 +347,8 @@ export function createEventStream( } /** - * @deprecated use event-stream implementation of the sync endpoint - * */ + * @deprecated use event-stream implementation of the sync endpoint + */ export function createHttpResponse( res: Response, ): DocsSynchronizerSyncOpts { From c1168bb44012a75f1237fd28da03a465275eaa3d Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 4 Mar 2022 17:06:40 +0100 Subject: [PATCH 12/12] Create polite-apples-relax.md Signed-off-by: Patrik Oldsberg --- .changeset/polite-apples-relax.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/polite-apples-relax.md diff --git a/.changeset/polite-apples-relax.md b/.changeset/polite-apples-relax.md new file mode 100644 index 0000000000..f6d10aaabf --- /dev/null +++ b/.changeset/polite-apples-relax.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': patch +--- + +Fixed display of the location in the log message that is printed when entity envelope validation fails.