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/chilly-comics-jam.md b/.changeset/chilly-comics-jam.md new file mode 100644 index 0000000000..92d7f9014e --- /dev/null +++ b/.changeset/chilly-comics-jam.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-react': minor +--- + +**BREAKING**: Removed `reduceCatalogFilters` and `reduceEntityFilters` due to low external utility value. 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/.changeset/lazy-points-explain.md b/.changeset/lazy-points-explain.md new file mode 100644 index 0000000000..ced31c2195 --- /dev/null +++ b/.changeset/lazy-points-explain.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': minor +--- + +**BREAKING**: Removed `ScaffolderTaskOutput.entityRef` and `ScaffolderTaskOutput.remoteUrl`, which both have been deprecated for over a year. Please use the `links` output instead. 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/.changeset/many-swans-sort.md b/.changeset/many-swans-sort.md new file mode 100644 index 0000000000..fec613cf00 --- /dev/null +++ b/.changeset/many-swans-sort.md @@ -0,0 +1,10 @@ +--- +'@backstage/plugin-catalog-backend': patch +--- + +**BREAKING**: + +- Removed the previously deprecated `runPeriodically` export. Please use the `@backstage/backend-tasks` package instead, or copy [the actual implementation](https://github.com/backstage/backstage/blob/02875d4d56708c60f86f6b0a5b3da82e24988354/plugins/catalog-backend/src/util/runPeriodically.ts#L29) into your own code if you explicitly do not want coordination of task runs across your worker nodes. +- Removed the previously deprecated `CatalogProcessorLocationResult.optional` field. Please set the corresponding `LocationSpec.presence` field to `'optional'` instead. +- Related to the previous point, the `processingResult.location` function no longer has a second boolean `optional` argument. Please set the corresponding `LocationSpec.presence` field to `'optional'` instead. +- Removed the previously deprecated `StaticLocationProcessor`. It has not been in use for some time; its functionality is covered by `ConfigLocationEntityProvider` instead. diff --git a/.changeset/nasty-seahorses-bathe.md b/.changeset/nasty-seahorses-bathe.md new file mode 100644 index 0000000000..884313e422 --- /dev/null +++ b/.changeset/nasty-seahorses-bathe.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-catalog': patch +'@backstage/plugin-rollbar': patch +--- + +Removed usage of removed hook. diff --git a/.changeset/nice-windows-push.md b/.changeset/nice-windows-push.md new file mode 100644 index 0000000000..2d04141cf1 --- /dev/null +++ b/.changeset/nice-windows-push.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-react': minor +--- + +**BREAKING**: Removed `useEntityCompoundName`, use `useRouteRefParams(entityRouteRef)` instead. diff --git a/.changeset/patched.json b/.changeset/patched.json index 1029c8f106..dd63e86169 100644 --- a/.changeset/patched.json +++ b/.changeset/patched.json @@ -1,3 +1,10 @@ { - "currentReleaseVersion": {} + "currentReleaseVersion": { + "@backstage/backend-common": "0.12.1", + "@backstage/catalog-model": "0.12.1", + "@backstage/cli": "0.15.1", + "@backstage/plugin-catalog-backend": "0.23.1", + "@backstage/plugin-catalog-common": "0.2.1", + "@backstage/plugin-catalog-react": "0.8.1" + } } diff --git a/.changeset/popular-boxes-develop.md b/.changeset/popular-boxes-develop.md new file mode 100644 index 0000000000..65aae2c7df --- /dev/null +++ b/.changeset/popular-boxes-develop.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Applied the fix from version `0.15.1` of this package, which was part of the `v0.70.1` release of Backstage. diff --git a/.changeset/popular-rats-return.md b/.changeset/popular-rats-return.md new file mode 100644 index 0000000000..3a91e6d707 --- /dev/null +++ b/.changeset/popular-rats-return.md @@ -0,0 +1,9 @@ +--- +'@backstage/backend-common': patch +'@backstage/catalog-model': patch +'@backstage/plugin-catalog-backend': patch +'@backstage/plugin-catalog-common': patch +'@backstage/plugin-catalog-react': patch +--- + +Applied the fix for the `/alpha` entry point resolution that was part of the `v0.70.1` release of Backstage. diff --git a/.changeset/quiet-pens-wait.md b/.changeset/quiet-pens-wait.md new file mode 100644 index 0000000000..b7510eab3f --- /dev/null +++ b/.changeset/quiet-pens-wait.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-react': minor +--- + +**BREAKING**: Removed `useEntityListProvider` use `useEntityList` instead. 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/.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/two-mails-boil.md b/.changeset/two-mails-boil.md new file mode 100644 index 0000000000..22651f1bd4 --- /dev/null +++ b/.changeset/two-mails-boil.md @@ -0,0 +1,5 @@ +--- +'@backstage/catalog-client': minor +--- + +**BREAKING**: Removed `CatalogClient.getLocationByEntity` and `CatalogClient.getOriginLocationByEntity` which had previously been deprecated. Please use `CatalogApi.getLocationByRef` instead. Note that this only affects you if you were using `CatalogClient` (the class) directly, rather than `CatalogApi` (the interface), since it has been removed from the interface in an earlier release. 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/.github/styles/vocab.txt b/.github/styles/vocab.txt index c7971f6c52..6ed539530d 100644 --- a/.github/styles/vocab.txt +++ b/.github/styles/vocab.txt @@ -84,6 +84,7 @@ dockerfiles Dockerize dockerode Docusaurus +ecco env Env elasticsearch diff --git a/microsite/blog/2022-03-04-backstage-upgrade-helper.md b/microsite/blog/2022-03-04-backstage-upgrade-helper.md new file mode 100644 index 0000000000..a189e28cd5 --- /dev/null +++ b/microsite/blog/2022-03-04-backstage-upgrade-helper.md @@ -0,0 +1,56 @@ +--- +title: Avoid upgrade surprises with Backstage Upgrade Helper +author: Vincenzo Scamporlino, Spotify +authorURL: https://github.com/vinzscam +authorImageURL: https://avatars.githubusercontent.com/u/8433119?v=4 +--- + +![backstage header](assets/22-03-04/backstage-upgrade-helper-post-header.png) + +_TLDR;_ The Spotify team recently announced [Backstage Upgrade Helper](https://backstage.github.io/upgrade-helper): a tool that helps adopters keep their Backstage application up-to-date. **Spoiler alert**: this is also a hidden and heartwarming tale about the beauty of open source innovation. + + + +## Upgrading Backstage was a common pain point + +Without a doubt, one of the most exciting things about Backstage is our community. Step into our daily [Discord conversations](https://discord.gg/sBEF5VkG) and the monthly [Community Sessions](https://www.youtube.com/watch?v=0QMQYSTKAx0) and you’ll find a ton of great ideas, problem-solving, and support for one another. + +During one of these discussions, we realized we all shared the same pain point — upgrading a Backstage application. + +The Backstage open source project is in hyper-growth mode, where dozens of pull requests are merged each day. This means adopters need to go through the upgrade process more often in order to get the latest and greatest features. The Spotify team heard a lot of feedback about how painful and manual this process was — so we decided to tackle this problem during one of our internal Hack Days. + +At Spotify, we run Hack Days every month and a lot of ideas come from those sessions (in fact, the idea to open source Backstage itself [was born on a Hack Day](https://open.spotify.com/episode/332yTwGiILGKTS7dsHCj2P)!). During a brainstorming session, we noticed that another open source community faced a similar upgrading problem years back and came up with a really good solution. + +If you have ever worked on a React Native project, you might immediately recognize what we are referring to: The [React Native Upgrade Helper](https://github.com/react-native-community/upgrade-helper) — a web tool to support React Native developers in upgrading their apps — might have saved hours of your time. It certainly saved us hours of ours. So we looked into the project details and discovered it could fulfill our Backstage needs. + +We started by creating a fork from React Native’s open source project, applying a few changes on top of it to introduce Backstage support, and — _ecco_ — we had a new Backstage Upgrade Helper! In just a few days with pretty minimal effort, we created a product that would save a lot of time for the entire Backstage community. And we had fun at the same time (happy developers make happy code 😁 ). + +## So what is Backstage Upgrade Helper? + +The Backstage Upgrade Helper tool enables adopters to easily upgrade their Backstage app by using the power of git to create a diff between different versions. + +Whenever a new version of Backstage is released, the Helper scaffolds a new dummy Backstage app using the `backstage-create-app` cli utility and checks all the generated files in a specific git branch. After the branch is generated, it gets compared with all the existing ones, which results in generating specific git patches stored in specific files. By selecting the version of the current Backstage release together with the version you want to upgrade to, the UI knows which patch file needs to be picked up. + +So, now you can update your Backstage application in three steps rather than manually reading the changelogs of all the Backstage modules in reverse order. + +### To use the Upgrade Helper, follow these simple steps + +1. Go to the [Backstage Upgrade Helper](https://backstage.github.io/upgrade-helper) and enter your current release and the release you would like to upgrade to. + +2. Press **Show me how to upgrade!** After that, the feature spits out the changes between the two Backstage versions in a split-screen view for easy comparison. + + ![Backstage Upgrade Helper in action](assets/22-03-04/backstage-upgrade-helper.gif) + +3. Apply the suggested changes to your source code to correctly upgrade your app to the selected Backstage version. This will let you directly migrate from the version you’re currently using to the target version and skip all the intermediate steps you would have otherwise gone through manually reading all the changelogs. + +[Watch the Upgrade Helper demo](https://youtu.be/nYjI2j-lWEM?t=410). + +## Open source inspires + +Thus far, the Backstage Upgrade Helper has gotten a lot of good feedback from the community and we’re sure to see awesome contributions in the future. But all the credit behind this idea goes to the React Native community. + +With React Native’s open source contributions, we were able to quickly solve a tough problem for the entire Backstage community. Not only did React Native’s project save us time creating a new product, but it has also saved our adopters time upgrading Backstage. + +This is why we love working in open source. The hard work done for one community has the power to influence and inspire another community. We hope Backstage can do the same and pay it forward to other open source projects. + +For more Backstage Upgrade Helper resources, check out the [UI code](https://github.com/backstage/upgrade-helper) and the [git patches](https://github.com/backstage/upgrade-helper-diff). diff --git a/microsite/blog/assets/22-03-04/backstage-upgrade-helper-post-header.png b/microsite/blog/assets/22-03-04/backstage-upgrade-helper-post-header.png new file mode 100644 index 0000000000..c4bc4fdd25 Binary files /dev/null and b/microsite/blog/assets/22-03-04/backstage-upgrade-helper-post-header.png differ diff --git a/microsite/blog/assets/22-03-04/backstage-upgrade-helper.gif b/microsite/blog/assets/22-03-04/backstage-upgrade-helper.gif new file mode 100644 index 0000000000..eec16600f6 Binary files /dev/null and b/microsite/blog/assets/22-03-04/backstage-upgrade-helper.gif differ diff --git a/packages/backend-common/CHANGELOG.md b/packages/backend-common/CHANGELOG.md index 8a7b5ef528..70b2455a55 100644 --- a/packages/backend-common/CHANGELOG.md +++ b/packages/backend-common/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/backend-common +## 0.12.1 + +### Patch Changes + +- Fixed runtime resolution of the `/alpha` entry point. + ## 0.12.0 ### Minor Changes 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/catalog-client/api-report.md b/packages/catalog-client/api-report.md index 9bbb24463b..d85b9c4d0d 100644 --- a/packages/catalog-client/api-report.md +++ b/packages/catalog-client/api-report.md @@ -107,11 +107,6 @@ export class CatalogClient implements CatalogApi { request: GetEntityFacetsRequest, options?: CatalogRequestOptions, ): Promise; - // @deprecated (undocumented) - getLocationByEntity( - entity: Entity, - options?: CatalogRequestOptions, - ): Promise; getLocationById( id: string, options?: CatalogRequestOptions, @@ -120,11 +115,6 @@ export class CatalogClient implements CatalogApi { locationRef: string, options?: CatalogRequestOptions, ): Promise; - // @deprecated (undocumented) - getOriginLocationByEntity( - entity: Entity, - options?: CatalogRequestOptions, - ): Promise; refreshEntity( entityRef: string, options?: CatalogRequestOptions, diff --git a/packages/catalog-client/src/CatalogClient.ts b/packages/catalog-client/src/CatalogClient.ts index f2bc3ed8f6..53397d061e 100644 --- a/packages/catalog-client/src/CatalogClient.ts +++ b/packages/catalog-client/src/CatalogClient.ts @@ -15,8 +15,6 @@ */ import { - ANNOTATION_LOCATION, - ANNOTATION_ORIGIN_LOCATION, Entity, CompoundEntityRef, parseEntityRef, @@ -308,49 +306,6 @@ export class CatalogClient implements CatalogApi { }; } - /** - * @deprecated please use getLocationByRef instead - */ - async getOriginLocationByEntity( - entity: Entity, - options?: CatalogRequestOptions, - ): Promise { - const locationCompound = - entity.metadata.annotations?.[ANNOTATION_ORIGIN_LOCATION]; - if (!locationCompound) { - return undefined; - } - const all: { data: Location }[] = await this.requestRequired( - 'GET', - '/locations', - options, - ); - return all - .map(r => r.data) - .find(l => locationCompound === stringifyLocationRef(l)); - } - - /** - * @deprecated please use getLocationByRef instead - */ - async getLocationByEntity( - entity: Entity, - options?: CatalogRequestOptions, - ): Promise { - const locationCompound = entity.metadata.annotations?.[ANNOTATION_LOCATION]; - if (!locationCompound) { - return undefined; - } - const all: { data: Location }[] = await this.requestRequired( - 'GET', - '/locations', - options, - ); - return all - .map(r => r.data) - .find(l => locationCompound === stringifyLocationRef(l)); - } - /** * {@inheritdoc CatalogApi.getLocationByRef} */ diff --git a/packages/catalog-model/CHANGELOG.md b/packages/catalog-model/CHANGELOG.md index 72d4f8b04a..bea5f18f09 100644 --- a/packages/catalog-model/CHANGELOG.md +++ b/packages/catalog-model/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/catalog-model +## 0.12.1 + +### Patch Changes + +- Fixed runtime resolution of the `/alpha` entry point. + ## 0.12.0 ### Minor Changes diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index cfae3cab06..10f7ce1d69 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/cli +## 0.15.1 + +### Patch Changes + +- Fixed an issue where the release stage entry point of packages were not resolved correctly. + ## 0.15.0 ### Minor Changes diff --git a/packages/cli/src/commands/pack.ts b/packages/cli/src/commands/pack.ts index e646568980..6c88ac055f 100644 --- a/packages/cli/src/commands/pack.ts +++ b/packages/cli/src/commands/pack.ts @@ -23,6 +23,11 @@ const SKIPPED_KEYS = ['access', 'registry', 'tag', 'alphaTypes', 'betaTypes']; const PKG_PATH = 'package.json'; const PKG_BACKUP_PATH = 'package.json-prepack'; +function resolveEntrypoint(pkg: any, name: string) { + const targetEntry = pkg.publishConfig[name] || pkg[name]; + return targetEntry && joinPath('..', targetEntry); +} + // Writes e.g. alpha/package.json async function writeReleaseStageEntrypoint(pkg: any, stage: 'alpha' | 'beta') { await fs.ensureDir(paths.resolveTarget(stage)); @@ -31,9 +36,9 @@ async function writeReleaseStageEntrypoint(pkg: any, stage: 'alpha' | 'beta') { { name: pkg.name, version: pkg.version, - main: (pkg.publishConfig.main || pkg.main) && '..', - module: (pkg.publishConfig.module || pkg.module) && '..', - browser: (pkg.publishConfig.browser || pkg.browser) && '..', + main: resolveEntrypoint(pkg, 'main'), + module: resolveEntrypoint(pkg, 'module'), + browser: resolveEntrypoint(pkg, 'browser'), types: joinPath('..', pkg.publishConfig[`${stage}Types`]), }, { encoding: 'utf8', spaces: 2 }, diff --git a/packages/cli/src/lib/packager/copyPackageDist.ts b/packages/cli/src/lib/packager/copyPackageDist.ts index 03ac361006..439b087fd7 100644 --- a/packages/cli/src/lib/packager/copyPackageDist.ts +++ b/packages/cli/src/lib/packager/copyPackageDist.ts @@ -20,6 +20,11 @@ import { join as joinPath, resolve as resolvePath } from 'path'; const SKIPPED_KEYS = ['access', 'registry', 'tag', 'alphaTypes', 'betaTypes']; +function resolveEntrypoint(pkg: any, name: string) { + const targetEntry = pkg.publishConfig[name] || pkg[name]; + return targetEntry && joinPath('..', targetEntry); +} + // Writes e.g. alpha/package.json async function writeReleaseStageEntrypoint( pkg: any, @@ -32,9 +37,9 @@ async function writeReleaseStageEntrypoint( { name: pkg.name, version: pkg.version, - main: (pkg.publishConfig.main || pkg.main) && '..', - module: (pkg.publishConfig.module || pkg.module) && '..', - browser: (pkg.publishConfig.browser || pkg.browser) && '..', + main: resolveEntrypoint(pkg, 'main'), + module: resolveEntrypoint(pkg, 'module'), + browser: resolveEntrypoint(pkg, 'browser'), types: joinPath('..', pkg.publishConfig[`${stage}Types`]), }, { encoding: 'utf8', spaces: 2 }, 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/catalog-backend/CHANGELOG.md b/plugins/catalog-backend/CHANGELOG.md index fb197a65f5..d4a7d8b8d6 100644 --- a/plugins/catalog-backend/CHANGELOG.md +++ b/plugins/catalog-backend/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-catalog-backend +## 0.23.1 + +### Patch Changes + +- Marked `GithubMultiOrgReaderProcessor` as stable, as it was moved to `/alpha` by mistake. +- Fixed runtime resolution of the `/alpha` entry point. +- Updated dependencies + - @backstage/backend-common@0.12.1 + - @backstage/catalog-model@0.12.1 + - @backstage/plugin-catalog-common@0.2.1 + ## 0.23.0 ### Minor Changes diff --git a/plugins/catalog-backend/api-report.md b/plugins/catalog-backend/api-report.md index 0d9f306009..80a059095e 100644 --- a/plugins/catalog-backend/api-report.md +++ b/plugins/catalog-backend/api-report.md @@ -333,7 +333,6 @@ export type CatalogProcessorErrorResult = { export type CatalogProcessorLocationResult = { type: 'location'; location: LocationSpec; - optional?: boolean; }; // @public @@ -706,7 +705,7 @@ export type GithubMultiOrgConfig = Array<{ userNamespace: string | undefined; }>; -// @alpha +// @public export class GithubMultiOrgReaderProcessor implements CatalogProcessor { constructor(options: { integrations: ScmIntegrationRegistry; @@ -812,7 +811,7 @@ function inputError( // @public @deprecated (undocumented) function location_2( newLocation: LocationSpec, - optional?: boolean, + _optional?: boolean, ): CatalogProcessorResult; // @public (undocumented) @@ -1007,10 +1006,7 @@ export const processingResult: Readonly<{ atLocation: LocationSpec, message: string, ) => CatalogProcessorResult; - readonly location: ( - newLocation: LocationSpec, - optional?: boolean | undefined, - ) => CatalogProcessorResult; + readonly location: (newLocation: LocationSpec) => CatalogProcessorResult; readonly entity: ( atLocation: LocationSpec, newEntity: Entity, @@ -1074,22 +1070,6 @@ export interface RouterOptions { refreshService?: RefreshService; } -// @public @deprecated -export function runPeriodically(fn: () => any, delayMs: number): () => void; - -// @public @deprecated (undocumented) -export class StaticLocationProcessor implements StaticLocationProcessor { - constructor(staticLocations: LocationSpec[]); - // (undocumented) - static fromConfig(config: Config): StaticLocationProcessor; - // (undocumented) - readLocation( - location: LocationSpec, - _optional: boolean, - emit: CatalogProcessorEmit, - ): Promise; -} - // @public (undocumented) export class UrlReaderProcessor implements CatalogProcessor { constructor(options: { reader: UrlReader; logger: Logger_2 }); diff --git a/plugins/catalog-backend/src/api/deprecatedResult.ts b/plugins/catalog-backend/src/api/deprecatedResult.ts index ecacc62c65..e616f3cf7d 100644 --- a/plugins/catalog-backend/src/api/deprecatedResult.ts +++ b/plugins/catalog-backend/src/api/deprecatedResult.ts @@ -68,9 +68,9 @@ export function generalError( */ export function location( newLocation: LocationSpec, - optional?: boolean, + _optional?: boolean, ): CatalogProcessorResult { - return { type: 'location', location: newLocation, optional }; + return { type: 'location', location: newLocation }; } /** diff --git a/plugins/catalog-backend/src/api/processingResult.ts b/plugins/catalog-backend/src/api/processingResult.ts index 5ad908dc8b..2fc2c9eac7 100644 --- a/plugins/catalog-backend/src/api/processingResult.ts +++ b/plugins/catalog-backend/src/api/processingResult.ts @@ -54,11 +54,8 @@ export const processingResult = Object.freeze({ return { type: 'error', location: atLocation, error: new Error(message) }; }, - location( - newLocation: LocationSpec, - optional?: boolean, - ): CatalogProcessorResult { - return { type: 'location', location: newLocation, optional }; + location(newLocation: LocationSpec): CatalogProcessorResult { + return { type: 'location', location: newLocation }; }, entity(atLocation: LocationSpec, newEntity: Entity): CatalogProcessorResult { diff --git a/plugins/catalog-backend/src/api/processor.ts b/plugins/catalog-backend/src/api/processor.ts index 12a008edc7..3f274d13ea 100644 --- a/plugins/catalog-backend/src/api/processor.ts +++ b/plugins/catalog-backend/src/api/processor.ts @@ -147,8 +147,6 @@ export type CatalogProcessorEmit = (generated: CatalogProcessorResult) => void; export type CatalogProcessorLocationResult = { type: 'location'; location: LocationSpec; - /** @deprecated Set `location.presence = 'optional'` instead */ - optional?: boolean; }; /** @public */ diff --git a/plugins/catalog-backend/src/modules/core/StaticLocationProcessor.ts b/plugins/catalog-backend/src/modules/core/StaticLocationProcessor.ts deleted file mode 100644 index e22d011695..0000000000 --- a/plugins/catalog-backend/src/modules/core/StaticLocationProcessor.ts +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Config } from '@backstage/config'; -import { - processingResult, - CatalogProcessorEmit, - LocationSpec, -} from '../../api'; - -/** - * @deprecated no longer in use, replaced by the ConfigLocationEntityProvider. - * @public - */ -export class StaticLocationProcessor implements StaticLocationProcessor { - static fromConfig(config: Config): StaticLocationProcessor { - const locations: LocationSpec[] = []; - - const lConfigs = config.getOptionalConfigArray('catalog.locations') ?? []; - for (const lConfig of lConfigs) { - const type = lConfig.getString('type'); - const target = lConfig.getString('target'); - locations.push({ type, target }); - } - - return new StaticLocationProcessor(locations); - } - - constructor(private readonly staticLocations: LocationSpec[]) {} - - async readLocation( - location: LocationSpec, - _optional: boolean, - emit: CatalogProcessorEmit, - ): Promise { - if (location.type !== 'bootstrap') { - return false; - } - - for (const staticLocation of this.staticLocations) { - emit(processingResult.location(staticLocation)); - } - - return true; - } -} diff --git a/plugins/catalog-backend/src/modules/core/index.ts b/plugins/catalog-backend/src/modules/core/index.ts index 9d582bfb34..364cede069 100644 --- a/plugins/catalog-backend/src/modules/core/index.ts +++ b/plugins/catalog-backend/src/modules/core/index.ts @@ -28,6 +28,5 @@ export type { PlaceholderResolverRead, PlaceholderResolverResolveUrl, } from './PlaceholderProcessor'; -export { StaticLocationProcessor } from './StaticLocationProcessor'; export { UrlReaderProcessor } from './UrlReaderProcessor'; export { parseEntityYaml } from '../util/parse'; diff --git a/plugins/catalog-backend/src/modules/github/GithubMultiOrgReaderProcessor.ts b/plugins/catalog-backend/src/modules/github/GithubMultiOrgReaderProcessor.ts index 339119137a..dbd858fc0d 100644 --- a/plugins/catalog-backend/src/modules/github/GithubMultiOrgReaderProcessor.ts +++ b/plugins/catalog-backend/src/modules/github/GithubMultiOrgReaderProcessor.ts @@ -40,10 +40,11 @@ import { import { buildOrgHierarchy } from '../util/org'; /** - * @alpha * Extracts teams and users out of a multiple GitHub orgs namespaced per org. * * Be aware that this processor may not be compatible with future org structures in the catalog. + * + * @public */ export class GithubMultiOrgReaderProcessor implements CatalogProcessor { private readonly integrations: ScmIntegrationRegistry; diff --git a/plugins/catalog-backend/src/processing/ProcessorOutputCollector.ts b/plugins/catalog-backend/src/processing/ProcessorOutputCollector.ts index c3cc6e288b..ff12f2f3db 100644 --- a/plugins/catalog-backend/src/processing/ProcessorOutputCollector.ts +++ b/plugins/catalog-backend/src/processing/ProcessorOutputCollector.ts @@ -106,9 +106,8 @@ export class ProcessorOutputCollector { this.deferredEntities.push({ entity, locationKey: location }); } else if (i.type === 'location') { - const presence = i.optional ? 'optional' : 'required'; const entity = locationSpecToLocationEntity( - { presence, ...i.location }, + i.location, this.parentEntity, ); const locationKey = getEntityLocationRef(entity); diff --git a/plugins/catalog-backend/src/util/index.ts b/plugins/catalog-backend/src/util/index.ts index 13a9c84b0f..0b5a942e0c 100644 --- a/plugins/catalog-backend/src/util/index.ts +++ b/plugins/catalog-backend/src/util/index.ts @@ -14,5 +14,4 @@ * limitations under the License. */ -export * from './runPeriodically'; export * from './RecursivePartial'; diff --git a/plugins/catalog-backend/src/util/runPeriodically.ts b/plugins/catalog-backend/src/util/runPeriodically.ts deleted file mode 100644 index 361fb33b2f..0000000000 --- a/plugins/catalog-backend/src/util/runPeriodically.ts +++ /dev/null @@ -1,56 +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. - */ - -/** - * Runs a function repeatedly, with a fixed wait between invocations. - * - * Supports async functions, and silently ignores exceptions and rejections. - * - * @param fn - The function to run. May return a Promise. - * @param delayMs - The delay between a completed function invocation and the - * next. - * @returns A function that, when called, stops the invocation loop. - * @deprecated use \@backstage/backend-tasks package instead. - * @public - */ -export function runPeriodically(fn: () => any, delayMs: number): () => void { - let cancel: () => void; - let cancelled = false; - const cancellationPromise = new Promise(resolve => { - cancel = () => { - resolve(); - cancelled = true; - }; - }); - - const startRefresh = async () => { - while (!cancelled) { - try { - await fn(); - } catch { - // ignore intentionally - } - - await Promise.race([ - new Promise(resolve => setTimeout(resolve, delayMs)), - cancellationPromise, - ]); - } - }; - startRefresh(); - - return cancel!; -} diff --git a/plugins/catalog-common/CHANGELOG.md b/plugins/catalog-common/CHANGELOG.md index 707207eda4..badffd5f0a 100644 --- a/plugins/catalog-common/CHANGELOG.md +++ b/plugins/catalog-common/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/plugin-catalog-common +## 0.2.1 + +### Patch Changes + +- Fixed runtime resolution of the `/alpha` entry point. + ## 0.2.0 ### Minor Changes diff --git a/plugins/catalog-react/CHANGELOG.md b/plugins/catalog-react/CHANGELOG.md index 89e03aa445..b93a2f7451 100644 --- a/plugins/catalog-react/CHANGELOG.md +++ b/plugins/catalog-react/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-catalog-react +## 0.8.1 + +### Patch Changes + +- Fixed runtime resolution of the `/alpha` entry point. +- Updated dependencies + - @backstage/catalog-model@0.12.1 + ## 0.8.0 ### Minor Changes diff --git a/plugins/catalog-react/api-report.md b/plugins/catalog-react/api-report.md index a55c53ed2e..7f14550afc 100644 --- a/plugins/catalog-react/api-report.md +++ b/plugins/catalog-react/api-report.md @@ -387,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; @@ -470,16 +461,6 @@ export class MockStarredEntitiesApi implements StarredEntitiesApi { toggleStarred(entityRef: string): Promise; } -// @public @deprecated (undocumented) -export function reduceCatalogFilters( - filters: EntityFilter[], -): Record; - -// @public @deprecated (undocumented) -export function reduceEntityFilters( - filters: EntityFilter[], -): (entity: Entity) => boolean; - // @public export interface StarredEntitiesApi { starredEntitie$(): Observable>; @@ -515,16 +496,6 @@ export function useEntity(): { refresh?: VoidFunction; }; -// @public @deprecated -export const useEntityCompoundName: () => { - kind: string; - namespace: string; - name: string; -}; - -// @public @deprecated (undocumented) -export const useEntityFromUrl: () => EntityLoadingStatus; - // @public @deprecated export function useEntityKinds(): { error: Error | undefined; @@ -537,11 +508,6 @@ export function useEntityList< EntityFilters extends DefaultEntityFilters = DefaultEntityFilters, >(): EntityListContextProps; -// @public @deprecated -export function useEntityListProvider< - EntityFilters extends DefaultEntityFilters = DefaultEntityFilters, ->(): EntityListContextProps; - // @public export function useEntityOwnership(): { loading: boolean; diff --git a/plugins/catalog-react/src/hooks/index.ts b/plugins/catalog-react/src/hooks/index.ts index f0407f746c..a1cd933d01 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, @@ -25,11 +24,9 @@ export type { EntityProviderProps, AsyncEntityProviderProps, } from './useEntity'; -export { useEntityCompoundName } from './useEntityCompoundName'; export { EntityListContext, EntityListProvider, - useEntityListProvider, useEntityList, } from './useEntityListProvider'; export type { @@ -37,7 +34,6 @@ 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'; diff --git a/plugins/catalog-react/src/hooks/useEntity.tsx b/plugins/catalog-react/src/hooks/useEntity.tsx index f80f858dec..75a623aaed 100644 --- a/plugins/catalog-react/src/hooks/useEntity.tsx +++ b/plugins/catalog-react/src/hooks/useEntity.tsx @@ -14,17 +14,12 @@ * limitations under the License. */ import { Entity } from '@backstage/catalog-model'; -import { errorApiRef, useApi } 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 { useEntityCompoundName } from './useEntityCompoundName'; +import React, { ReactNode } from 'react'; /** @public */ export type EntityLoadingStatus = { @@ -100,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 } = useEntityCompoundName(); - 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. diff --git a/plugins/catalog-react/src/hooks/useEntityCompoundName.ts b/plugins/catalog-react/src/hooks/useEntityCompoundName.ts deleted file mode 100644 index 481c18f8a0..0000000000 --- a/plugins/catalog-react/src/hooks/useEntityCompoundName.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { entityRouteRef } from '../routes'; -import { useRouteRefParams } from '@backstage/core-plugin-api'; - -/** - * Grabs entity kind, namespace, and name from the location - * @public - * @deprecated use {@link @backstage/core-plugin-api#useRouteRefParams} instead - */ -export const useEntityCompoundName = () => { - const { kind, namespace, name } = useRouteRefParams(entityRouteRef); - return { kind, namespace, name }; -}; diff --git a/plugins/catalog-react/src/hooks/useEntityListProvider.tsx b/plugins/catalog-react/src/hooks/useEntityListProvider.tsx index 72dfb7d1c3..ccac475ae8 100644 --- a/plugins/catalog-react/src/hooks/useEntityListProvider.tsx +++ b/plugins/catalog-react/src/hooks/useEntityListProvider.tsx @@ -249,20 +249,6 @@ export const EntityListProvider = ({ ); }; -/** - * Hook for interacting with the entity list context provided by the {@link EntityListProvider}. - * @public - * @deprecated use {@link useEntityList} instead. - */ -export function useEntityListProvider< - EntityFilters extends DefaultEntityFilters = DefaultEntityFilters, ->(): EntityListContextProps { - const context = useContext(EntityListContext); - if (!context) - throw new Error('useEntityList must be used within EntityListProvider'); - return context; -} - /** * Hook for interacting with the entity list context provided by the {@link EntityListProvider}. * @public 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/index.ts b/plugins/catalog-react/src/index.ts index 2279d49a2c..6d5a5ad204 100644 --- a/plugins/catalog-react/src/index.ts +++ b/plugins/catalog-react/src/index.ts @@ -30,5 +30,12 @@ export * from './filters'; export { entityRouteParams, entityRouteRef } from './routes'; export * from './testUtils'; export * from './types'; -export * from './utils'; export * from './overridableComponents'; +export { + getEntityMetadataEditUrl, + getEntityMetadataViewUrl, + getEntityRelations, + getEntitySourceLocation, + isOwnerOf, +} from './utils'; +export type { EntitySourceLocation } from './utils'; diff --git a/plugins/catalog-react/src/utils/filters.ts b/plugins/catalog-react/src/utils/filters.ts index 68cd94fd6e..109e864c52 100644 --- a/plugins/catalog-react/src/utils/filters.ts +++ b/plugins/catalog-react/src/utils/filters.ts @@ -17,10 +17,6 @@ import { Entity } from '@backstage/catalog-model'; import { EntityFilter } from '../types'; -/** - * @public - * @deprecated will be made private. - */ export function reduceCatalogFilters( filters: EntityFilter[], ): Record { @@ -32,10 +28,6 @@ export function reduceCatalogFilters( }, {} as Record); } -/** - * @public - * @deprecated will be made private. - */ export function reduceEntityFilters( filters: EntityFilter[], ): (entity: Entity) => boolean { diff --git a/plugins/catalog/src/components/EntityLayout/EntityLayout.tsx b/plugins/catalog/src/components/EntityLayout/EntityLayout.tsx index 40c4f9e873..d4244419cb 100644 --- a/plugins/catalog/src/components/EntityLayout/EntityLayout.tsx +++ b/plugins/catalog/src/components/EntityLayout/EntityLayout.tsx @@ -33,15 +33,16 @@ import { attachComponentData, IconComponent, useElementFilter, + useRouteRefParams, } from '@backstage/core-plugin-api'; import { EntityRefLinks, + entityRouteRef, FavoriteEntity, getEntityRelations, InspectEntityDialog, UnregisterEntityDialog, useAsyncEntity, - useEntityCompoundName, } from '@backstage/plugin-catalog-react'; import { Box, TabProps } from '@material-ui/core'; import { Alert } from '@material-ui/lab'; @@ -176,7 +177,7 @@ export const EntityLayout = (props: EntityLayoutProps) => { UNSTABLE_contextMenuOptions, children, } = props; - const { kind, namespace, name } = useEntityCompoundName(); + const { kind, namespace, name } = useRouteRefParams(entityRouteRef); const { entity, loading, error } = useAsyncEntity(); const location = useLocation(); const routes = useElementFilter( diff --git a/plugins/rollbar/src/hooks/useCatalogEntity.ts b/plugins/rollbar/src/hooks/useCatalogEntity.ts index 21d22dd13c..4845a275be 100644 --- a/plugins/rollbar/src/hooks/useCatalogEntity.ts +++ b/plugins/rollbar/src/hooks/useCatalogEntity.ts @@ -14,16 +14,13 @@ * limitations under the License. */ -import { - catalogApiRef, - useEntityCompoundName, -} from '@backstage/plugin-catalog-react'; +import { catalogApiRef, entityRouteRef } from '@backstage/plugin-catalog-react'; import useAsync from 'react-use/lib/useAsync'; -import { useApi } from '@backstage/core-plugin-api'; +import { useApi, useRouteRefParams } from '@backstage/core-plugin-api'; export function useCatalogEntity() { const catalogApi = useApi(catalogApiRef); - const { namespace, name } = useEntityCompoundName(); + const { namespace, name } = useRouteRefParams(entityRouteRef); const { value: entity, diff --git a/plugins/scaffolder-backend/api-report.md b/plugins/scaffolder-backend/api-report.md index b18e199f40..612ddedecc 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'; @@ -21,7 +19,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'; @@ -63,8 +60,6 @@ export interface CreateBuiltInActionsOptions { catalogClient: CatalogApi; // (undocumented) config: Config; - // @deprecated (undocumented) - containerRunner?: ContainerRunner; // (undocumented) integrations: ScmIntegrations; // (undocumented) @@ -99,8 +94,6 @@ export function createDebugLogAction(): TemplateAction<{ listWorkspace?: boolean | undefined; }>; -export { createFetchCookiecutterAction }; - // @public export function createFetchPlainAction(options: { reader: UrlReader; @@ -388,25 +381,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) @@ -428,8 +402,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/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'; 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, diff --git a/plugins/scaffolder/api-report.md b/plugins/scaffolder/api-report.md index b51f18fcc9..9326a61fd5 100644 --- a/plugins/scaffolder/api-report.md +++ b/plugins/scaffolder/api-report.md @@ -314,6 +314,14 @@ export interface ScaffolderGetIntegrationsListResponse { }[]; } +// @public (undocumented) +export type ScaffolderOutputLink = { + title?: string; + icon?: string; + url?: string; + entityRef?: string; +}; + // Warning: (ae-missing-release-tag) "ScaffolderPage" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -372,12 +380,8 @@ export type ScaffolderTask = { createdAt: string; }; -// Warning: (ae-missing-release-tag) "ScaffolderTaskOutput" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type ScaffolderTaskOutput = { - entityRef?: string; - remoteUrl?: string; links?: ScaffolderOutputLink[]; } & { [key: string]: unknown; @@ -451,8 +455,4 @@ export const TemplateTypePicker: () => JSX.Element | null; // @public export const useTemplateSecrets: () => ScaffolderUseTemplateSecrets; - -// Warnings were encountered during analysis: -// -// src/types.d.ts:32:5 - (ae-forgotten-export) The symbol "ScaffolderOutputLink" needs to be exported by the entry point index.d.ts ``` diff --git a/plugins/scaffolder/src/components/TaskPage/TaskPage.tsx b/plugins/scaffolder/src/components/TaskPage/TaskPage.tsx index e0445ed641..aab5e8348a 100644 --- a/plugins/scaffolder/src/components/TaskPage/TaskPage.tsx +++ b/plugins/scaffolder/src/components/TaskPage/TaskPage.tsx @@ -217,12 +217,8 @@ export const TaskStatusStepper = memo( }, ); -const hasLinks = ({ - entityRef, - remoteUrl, - links = [], -}: ScaffolderTaskOutput): boolean => - !!(entityRef || remoteUrl || links.length > 0); +const hasLinks = ({ links = [] }: ScaffolderTaskOutput): boolean => + links.length > 0; /** * TaskPageProps for constructing a TaskPage diff --git a/plugins/scaffolder/src/components/TaskPage/TaskPageLinks.test.tsx b/plugins/scaffolder/src/components/TaskPage/TaskPageLinks.test.tsx index 8316b67ff5..2f5d015f8d 100644 --- a/plugins/scaffolder/src/components/TaskPage/TaskPageLinks.test.tsx +++ b/plugins/scaffolder/src/components/TaskPage/TaskPageLinks.test.tsx @@ -26,43 +26,6 @@ describe('TaskPageLinks', () => { jest.resetAllMocks(); }); - it('renders the entityRef link', async () => { - const output = { entityRef: 'Component:default/my-app' }; - const { findByText } = await renderInTestApp( - , - { - mountedRoutes: { - '/catalog/:namespace/:kind/:name/*': entityRouteRef, - }, - }, - ); - - const element = await findByText('Open in catalog'); - - expect(element).toBeInTheDocument(); - expect(element).toHaveAttribute( - 'href', - '/catalog/default/Component/my-app', - ); - }); - - it('renders the remoteUrl link', async () => { - const output = { remoteUrl: 'https://remote.url' }; - const { findByText } = await renderInTestApp( - , - { - mountedRoutes: { - '/catalog/:namespace/:kind/:name/*': entityRouteRef, - }, - }, - ); - - const element = await findByText('Repo'); - - expect(element).toBeInTheDocument(); - expect(element).toHaveAttribute('href', 'https://remote.url'); - }); - it('renders further links', async () => { const output = { links: [ diff --git a/plugins/scaffolder/src/components/TaskPage/TaskPageLinks.tsx b/plugins/scaffolder/src/components/TaskPage/TaskPageLinks.tsx index 5451b4e725..cb77689b6e 100644 --- a/plugins/scaffolder/src/components/TaskPage/TaskPageLinks.tsx +++ b/plugins/scaffolder/src/components/TaskPage/TaskPageLinks.tsx @@ -28,29 +28,13 @@ type TaskPageLinksProps = { }; export const TaskPageLinks = ({ output }: TaskPageLinksProps) => { - const { entityRef: entityRefOutput, remoteUrl } = output; - let { links = [] } = output; + const { links = [] } = output; const app = useApp(); const entityRoute = useRouteRef(entityRouteRef); const iconResolver = (key?: string): IconComponent => key ? app.getSystemIcon(key) ?? LanguageIcon : LanguageIcon; - if (remoteUrl) { - links = [{ url: remoteUrl, title: 'Repo' }, ...links]; - } - - if (entityRefOutput) { - links = [ - { - entityRef: entityRefOutput, - title: 'Open in catalog', - icon: 'catalog', - }, - ...links, - ]; - } - return ( {links 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]); +} diff --git a/plugins/scaffolder/src/index.ts b/plugins/scaffolder/src/index.ts index f33cf289f4..34b9155d66 100644 --- a/plugins/scaffolder/src/index.ts +++ b/plugins/scaffolder/src/index.ts @@ -28,6 +28,7 @@ export type { ScaffolderApi, ScaffolderGetIntegrationsListOptions, ScaffolderGetIntegrationsListResponse, + ScaffolderOutputLink, ScaffolderScaffoldOptions, ScaffolderScaffoldResponse, ScaffolderStreamLogsOptions, diff --git a/plugins/scaffolder/src/types.ts b/plugins/scaffolder/src/types.ts index 0ffbd601a8..069c28d85c 100644 --- a/plugins/scaffolder/src/types.ts +++ b/plugins/scaffolder/src/types.ts @@ -43,18 +43,16 @@ export type ListActionsResponse = Array<{ }; }>; -type ScaffolderOutputLink = { +/** @public */ +export type ScaffolderOutputLink = { title?: string; icon?: string; url?: string; entityRef?: string; }; +/** @public */ export type ScaffolderTaskOutput = { - /** @deprecated use the `links` property to link out to relevant resources */ - entityRef?: string; - /** @deprecated use the `links` property to link out to relevant resources */ - remoteUrl?: string; links?: ScaffolderOutputLink[]; } & { [key: string]: unknown;