From bd62490a00339ba94a66b874bac911b1e77f0793 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Mon, 30 Oct 2023 10:10:19 +0100 Subject: [PATCH 001/275] WIP. Adding the Gitea RepoUrlPicker Signed-off-by: cmoulliard --- .../RepoUrlPicker/GiteaRepoPicker.test.tsx | 40 ++++++++++ .../fields/RepoUrlPicker/GiteaRepoPicker.tsx | 75 +++++++++++++++++++ .../fields/RepoUrlPicker/RepoUrlPicker.tsx | 10 +++ .../components/fields/RepoUrlPicker/schema.ts | 4 + .../components/fields/RepoUrlPicker/utils.ts | 1 - 5 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 plugins/scaffolder/src/components/fields/RepoUrlPicker/GiteaRepoPicker.test.tsx create mode 100644 plugins/scaffolder/src/components/fields/RepoUrlPicker/GiteaRepoPicker.tsx diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/GiteaRepoPicker.test.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/GiteaRepoPicker.test.tsx new file mode 100644 index 0000000000..e66ca49af1 --- /dev/null +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/GiteaRepoPicker.test.tsx @@ -0,0 +1,40 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { GiteaRepoPicker } from './GiteaRepoPicker'; +import { render, fireEvent } from '@testing-library/react'; + +describe('GiteaRepoPicker', () => { + describe('owner input field', () => { + it('calls onChange when the owner input changes', () => { + const onChange = jest.fn(); + const { getAllByRole } = render( + , + ); + + const ownerInput = getAllByRole('textbox')[0]; + + fireEvent.change(ownerInput, { target: { value: 'test-owner' } }); + + expect(onChange).toHaveBeenCalledWith({ owner: 'test-owner' }); + }); + }); +}); diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/GiteaRepoPicker.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/GiteaRepoPicker.tsx new file mode 100644 index 0000000000..566a2732e3 --- /dev/null +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/GiteaRepoPicker.tsx @@ -0,0 +1,75 @@ +/* + * 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 React from 'react'; +import FormControl from '@material-ui/core/FormControl'; +import FormHelperText from '@material-ui/core/FormHelperText'; +import Input from '@material-ui/core/Input'; +import InputLabel from '@material-ui/core/InputLabel'; +import { Select, SelectItem } from '@backstage/core-components'; +import { RepoUrlPickerState } from './types'; + +export const GiteaRepoPicker = (props: { + allowedOwners?: string[]; + allowedRepos?: string[]; + state: RepoUrlPickerState; + onChange: (state: RepoUrlPickerState) => void; + rawErrors: string[]; +}) => { + const { allowedOwners = [], state, onChange, rawErrors } = props; + const ownerItems: SelectItem[] = allowedOwners + ? allowedOwners.map(i => ({ label: i, value: i })) + : [{ label: 'Loading...', value: 'loading' }]; + + const { owner } = state; + + return ( + <> + 0 && !owner} + > + {allowedOwners?.length ? ( + onChange({ owner: e.target.value })} + value={owner} + /> + + )} + + Gitea namespace where this repository will belong to. It can be the + name of organization, group, subgroup, user, or the project. + + + + ); +}; diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx index 57cebb3d96..bfb6252876 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx @@ -20,6 +20,7 @@ import { } from '@backstage/integration-react'; import React, { useEffect, useState, useMemo, useCallback } from 'react'; import { GithubRepoPicker } from './GithubRepoPicker'; +import { GiteaRepoPicker } from './GiteaRepoPicker'; import { GitlabRepoPicker } from './GitlabRepoPicker'; import { AzureRepoPicker } from './AzureRepoPicker'; import { BitbucketRepoPicker } from './BitbucketRepoPicker'; @@ -174,6 +175,15 @@ export const RepoUrlPicker = (props: RepoUrlPickerProps) => { state={state} /> )} + {hostType === 'gitea' && ( + + )} {hostType === 'gitlab' && ( Date: Tue, 14 Nov 2023 10:49:21 +0100 Subject: [PATCH 002/275] Update how-to-guides.md Added new section in doc, to prevent download of Google fonts Signed-off-by: Antonino Provenzano --- docs/features/techdocs/how-to-guides.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/features/techdocs/how-to-guides.md b/docs/features/techdocs/how-to-guides.md index 29f985904f..8415640569 100644 --- a/docs/features/techdocs/how-to-guides.md +++ b/docs/features/techdocs/how-to-guides.md @@ -483,6 +483,8 @@ plugins: - techdocs-core ``` +note: + 3. Create a `/docs` folder in the skeleton folder with at least an `index.md` file in it. @@ -504,6 +506,18 @@ folder (/docs) or replace the content in this file. Done! You now have support for TechDocs in your own software template! +### Prevent download of Google fonts + +If your Backstage instance does not have internet access, the generation will fail. TechDocs tries to download the Roboto font from Google. You can disable it by adding the following lines to mkdocs.yaml: + +```markdown +theme: + name: material + font: false +``` + +note: The addition "name material" is necessary. Otherwise it will not work + ## How to enable iframes in TechDocs TechDocs uses the [DOMPurify](https://github.com/cure53/DOMPurify) library to From 6fb909f0119590adead8a8d2aa6e08cf7883ea95 Mon Sep 17 00:00:00 2001 From: Alex Crome Date: Wed, 15 Nov 2023 22:34:11 +0000 Subject: [PATCH 003/275] More Backend Migration Docs * Added more documentation on migrating catalog modules to the new backend system. (A-Github) * Tweaked a few existing documentation page to recommend schedules are set via Signed-off-by: Alex Crome --- .../building-backends/08-migrating.md | 258 +++++++++++++++++- docs/integrations/aws-s3/discovery.md | 10 +- docs/integrations/azure/discovery.md | 2 +- docs/integrations/bitbucketCloud/discovery.md | 17 +- .../integrations/bitbucketServer/discovery.md | 10 +- docs/integrations/gerrit/discovery.md | 9 +- docs/integrations/github/discovery.md | 27 +- 7 files changed, 269 insertions(+), 64 deletions(-) diff --git a/docs/backend-system/building-backends/08-migrating.md b/docs/backend-system/building-backends/08-migrating.md index 98dde46d38..b20e5a98e1 100644 --- a/docs/backend-system/building-backends/08-migrating.md +++ b/docs/backend-system/building-backends/08-migrating.md @@ -262,9 +262,259 @@ If you have other customizations made to `plugins/catalog.ts`, such as adding custom processors or entity providers, read on. Otherwise, you should be able to just delete that file at this point. +#### Amazon Web Services + +`AwsEksClusterProcessor` and `AwsOrganizationCloudAccountProcessor` have not yet been migrated to the new backend system. +See [Other Catalog Extensions](#other-catalog-extensions) for how to use these in the new backend system. + +For `AwsS3DiscoveryProcessor`, first migrate to `AwsS3EntityProvider`. + +To migrate `AwsS3EntityProvider` to the new backend system, add a reference to the `@backstage/plugin-catalog-backend-module-aws` module. + +```ts title="packages/backend/src/index.ts" +backend.add(import('@backstage/plugin-catalog-backend/alpha')); +/* highlight-add-start */ +backend.add(import('@backstage/plugin-catalog-backend-module-aws/alpha')); +/* highlight-add-end */ +``` + +If you were providing a `schedule` in code, this now needs to be set via configuration. +All other AWS configuration in `app-config.yaml` remains the same. + +```yaml title="app-config.yaml" +catalog: + providers: + awsS3: + yourProviderId: + # ... + /* highlight-add-start */ + schedule: + frequency: PT1H + timeout: PT50M + /* highlight-add-end */ +``` + +#### Azure Devops + +For `AzureDevOpsDiscoveryProcessor`, first migrate to `AzureDevOpsEntityProvider`. + +To migrate `AzureDevOpsEntityProvider` to the new backend system, add a reference to the `@backstage/plugin-catalog-backend-module-azure` module. + +```ts title="packages/backend/src/index.ts" +backend.add(import('@backstage/plugin-catalog-backend/alpha')); +/* highlight-add-start */ +backend.add(import('@backstage/plugin-catalog-backend-module-azure/alpha')); +/* highlight-add-end */ +``` + +If you were providing a `schedule` in code, this now needs to be set via configuration. +All other Azure DevOps configuration in `app-config.yaml` remains the same. + +```yaml title="app-config.yaml" +catalog: + providers: + azureDevOps: + yourProviderId: + # ... + /* highlight-add-start */ + schedule: + frequency: PT1H + timeout: PT50M + /* highlight-add-end */ +``` + +#### Open API + +`InternalOpenApiDocumentationProvider` have not yet been migrated to the new backend system. +See [Other Catalog Extensions](#other-catalog-extensions) for how to use this in the new backend system. + +#### Bitbucket + +For `BitbucketDiscoveryProcessor`, migrate to `BitbucketCloudEntityProvider` or `BitbucketServerEntityProvider` + +To migrate `BitbucketCloudEntityProvider` to the new backend system, add a reference to the `@backstage/plugin-catalog-backend-module-bitbucket-cloud` module. + +```ts title="packages/backend/src/index.ts" +backend.add(import('@backstage/plugin-catalog-backend/alpha')); +/* highlight-add-start */ +backend.add( + import('@backstage/plugin-catalog-backend-module-bitbucket-cloud/alpha'), +); +/* highlight-add-end */ +``` + +If you were providing a `schedule` in code, this now needs to be set via configuration. +All other Bitbucket Cloud configuration in `app-config.yaml` remains the same. + +```yaml title="app-config.yaml" +catalog: + providers: + bitbucketCloud: + yourProviderId: + # ... + /* highlight-add-start */ + schedule: + frequency: PT30M + timeout: PT3M + /* highlight-add-end */ +``` + +To migrate `BitbucketServerEntityProvider` to the new backend system, add a reference to `@backstage/plugin-catalog-backend-module-bitbucket-server`. + +```ts title="packages/backend/src/index.ts" +backend.add(import('@backstage/plugin-catalog-backend/alpha')); +/* highlight-add-start */ +backend.add( + import('@backstage/plugin-catalog-backend-module-bitbucket-server/alpha'), +); +/* highlight-add-end */ +``` + +If you were providing a `schedule` in code, this now needs to be set via configuration. +All other Bitbucket Server configuration in `app-config.yaml` remains the same. + +```yaml title="app-config.yaml" +catalog: + providers: + bitbucketServer: + yourProviderId: + # ... + /* highlight-add-start */ + schedule: + frequency: PT30M + timeout: PT3M + /* highlight-add-end */ +``` + +#### Google Cloud Platform + +To migrate `GkeEntityProvider` to the new backend system, add a reference to `@backstage/plugin-catalog-backend-module-gcp`. + +```ts title="packages/backend/src/index.ts" +backend.add(import('@backstage/plugin-catalog-backend/alpha')); +/* highlight-add-start */ +backend.add(import('@backstage/plugin-catalog-backend-module-gcp')); +/* highlight-add-end */ +``` + +Configuration in app-config.yaml remains the same. + +#### Gerrit + +To migrate `GerritEntityProvider` to the new backend system, add a reference to `@backstage/plugin-catalog-backend-module-gerrit`. + +```ts title="packages/backend/src/index.ts" +backend.add(import('@backstage/plugin-catalog-backend/alpha')); +/* highlight-add-start */ +backend.add(import('@backstage/plugin-catalog-backend-module-gerrit/alpha')); +/* highlight-add-end */ +``` + +If you were providing a `schedule` in code, this now needs to be set via configuration. +All other Gerrit configuration in `app-config.yaml` remains the same. + +```yaml title="app-config.yaml" +catalog: + providers: + gerrit: + yourProviderId: + # ... + /* highlight-add-start */ + schedule: + frequency: PT30M + timeout: PT3M + /* highlight-add-end */ +``` + +#### Github + +For `GithubDiscoveryProcessor`, `GithubMultiOrgReaderProcessor` and `GithubOrgReaderProcessor`, first migrate to the equivalent Entity Provider. + +To migrate `GithubEntityProvider` to the new backend system, add a reference to `@backstage/plugin-catalog-backend-module-github`. + +```ts title="packages/backend/src/index.ts" +backend.add(import('@backstage/plugin-catalog-backend/alpha')); +/* highlight-add-start */ +backend.add(import('@backstage/plugin-catalog-backend-module-github/alpha')); +/* highlight-add-end */ +``` + +If you were providing a `schedule` in code, this now needs to be set via configuration. +All other Github configuration in `app-config.yaml` remains the same. + +```yaml title="app-config.yaml" +catalog: + providers: + github: + yourProviderId: + # ... + /* highlight-add-start */ + schedule: + frequency: PT30M + timeout: PT3M + /* highlight-add-end */ +``` + +To migrate `GithubMultiOrgEntityProvider` and `GithubOrgEntityProvider` to the new backend system, add a reference to `@backstage/plugin-catalog-backend-module-github-org`. + +```ts title="packages/backend/src/index.ts" +backend.add(import('@backstage/plugin-catalog-backend/alpha')); +/* highlight-add-start */ +backend.add(import('@backstage/plugin-catalog-backend-module-github-org')); +/* highlight-add-end */ +``` + +If you were providing a `schedule` in code, this now needs to be set via configuration. +All other Github configuration in `app-config.yaml` remains the same. + +```yaml title="app-config.yaml" +catalog: + providers: + githubOrg: + yourProviderId: + # ... + /* highlight-add-start */ + schedule: + frequency: PT30M + timeout: PT3M + /* highlight-add-end */ +``` + +If you were providing transformers, these can be configured by extending `githubOrgEntityProviderTransformsExtensionPoint` + +```ts title="packages/backend/src/index.ts" +import { createBackendModule } from '@backstage/backend-plugin-api'; +import { githubOrgEntityProviderTransformsExtensionPoint } from '@backstage/plugin-catalog-backend-module-github-org'; + +backend.add( + createBackendModule({ + pluginId: 'catalog', + moduleId: 'githubOrgTransformers', + register(env) { + env.registerInit({ + deps: { + /* highlight-add-start */ + githubOrgTransformers: + githubOrgEntityProviderTransformsExtensionPoint, + /* highlight-add-end */ + }, + async init({ githubOrgTransformers }) { + /* highlight-add-start */ + githubOrgTransformers.setUserTransformer(myUserTransformer); + githubOrgTransformers.setTeamTransformer(myTeamTransformer); + /* highlight-add-end */ + }, + }); + }, + }), +); +``` + #### Microsoft Graph -Import the Microsoft Graph catalog module +For `MicrosoftGraphOrgReaderProcessor`, first migrate to `MicrosoftGraphOrgEntityProvider` + +To migrate `MicrosoftGraphOrgEntityProvider` to the new backend system, add a reference to `@backstage/plugin-catalog-backend-module-github-org`. ```ts title="packages/backend/src/index.ts" backend.add(import('@backstage/plugin-catalog-backend/alpha')); @@ -273,7 +523,8 @@ backend.add(import('@backstage/plugin-catalog-backend-module-msgraph/alpha')); /* highlight-add-end */ ``` -If you were providng a `schedule` programtically, this now needs to be set via configuration +If you were providing a `schedule` in code, this now needs to be set via configuration +All other Microsoft Graph configuration in `app-config.yaml` remains the same. ```yaml title="app-config.yaml" catalog: @@ -285,7 +536,6 @@ catalog: frequency: PT4H timeout: PT30M /* highlight-add-end */ - ``` If you were providing transformers, these can be configured by extending `microsoftGraphOrgEntityProviderTransformExtensionPoint` @@ -297,7 +547,7 @@ import { microsoftGraphOrgEntityProviderTransformExtensionPoint } from '@backsta backend.add( createBackendModule({ pluginId: 'catalog', - moduleId: 'microsoftGraphExtensions', + moduleId: 'microsoftGraphTransformers', register(env) { env.registerInit({ deps: { diff --git a/docs/integrations/aws-s3/discovery.md b/docs/integrations/aws-s3/discovery.md index 4a2b953bc9..ceb780141f 100644 --- a/docs/integrations/aws-s3/discovery.md +++ b/docs/integrations/aws-s3/discovery.md @@ -32,7 +32,7 @@ catalog: bucketName: sample-bucket prefix: prefix/ # optional region: us-east-2 # optional, uses the default region otherwise - schedule: # optional; same options as in TaskScheduleDefinition + schedule: # same options as in TaskScheduleDefinition # supports cron, ISO duration, "human duration" as used in code frequency: { minutes: 30 } # supports ISO duration, "human duration" as used in code @@ -52,7 +52,7 @@ catalog: bucketName: sample-bucket prefix: prefix/ # optional region: us-east-2 # optional, uses the default region otherwise - schedule: # optional; same options as in TaskScheduleDefinition + schedule: # same options as in TaskScheduleDefinition # supports cron, ISO duration, "human duration" as used in code frequency: { minutes: 30 } # supports ISO duration, "human duration" as used in code @@ -79,12 +79,6 @@ const builder = await CatalogBuilder.create(env); builder.addEntityProvider( AwsS3EntityProvider.fromConfig(env.config, { logger: env.logger, - // optional: alternatively, use scheduler with schedule defined in app-config.yaml - schedule: env.scheduler.createScheduledTaskRunner({ - frequency: { minutes: 30 }, - timeout: { minutes: 3 }, - }), - // optional: alternatively, use schedule scheduler: env.scheduler, }), ); diff --git a/docs/integrations/azure/discovery.md b/docs/integrations/azure/discovery.md index 7b91308b56..3b25a9ac75 100644 --- a/docs/integrations/azure/discovery.md +++ b/docs/integrations/azure/discovery.md @@ -71,7 +71,7 @@ The parameters available are: - **`repository:`** _(optional)_ The repository name. Wildcards are supported as show on the examples above. If not set, all repositories will be searched. - **`path:`** _(optional)_ Where to find catalog-info.yaml files. Defaults to /catalog-info.yaml. - **`branch:`** _(optional)_ The branch name to use. -- **`schedule`** _(optional)_: +- **`schedule`**: - **`frequency`**: How often you want the task to run. The system does its best to avoid overlapping invocations. - **`timeout`**: diff --git a/docs/integrations/bitbucketCloud/discovery.md b/docs/integrations/bitbucketCloud/discovery.md index 6e1533dea0..53315a4c48 100644 --- a/docs/integrations/bitbucketCloud/discovery.md +++ b/docs/integrations/bitbucketCloud/discovery.md @@ -49,19 +49,6 @@ export default async function createPlugin( } ``` -Alternatively to the config-based schedule, you can use - -```ts -/* highlight-remove-next-line */ -scheduler: env.scheduler, -/* highlight-add-start */ -schedule: env.scheduler.createScheduledTaskRunner({ - frequency: { minutes: 30 }, - timeout: { minutes: 3 }, -}), -/* highlight-add-end */ -``` - ### Installation with Events Support Please follow the installation instructions at @@ -131,7 +118,7 @@ catalog: filters: # optional projectKey: '^apis-.*$' # optional; RegExp repoSlug: '^service-.*$' # optional; RegExp - schedule: # optional; same options as in TaskScheduleDefinition + schedule: # same options as in TaskScheduleDefinition # supports cron, ISO duration, "human duration" as used in code frequency: { minutes: 30 } # supports ISO duration, "human duration" as used in code @@ -153,7 +140,7 @@ catalog: Regular expression used to filter results based on the project key. - **`repoSlug`** _(optional)_: Regular expression used to filter results based on the repo slug. -- **`schedule`** _(optional)_: +- **`schedule`**: - **`frequency`**: How often you want the task to run. The system does its best to avoid overlapping invocations. - **`timeout`**: diff --git a/docs/integrations/bitbucketServer/discovery.md b/docs/integrations/bitbucketServer/discovery.md index 05d0510553..ad59006ff1 100644 --- a/docs/integrations/bitbucketServer/discovery.md +++ b/docs/integrations/bitbucketServer/discovery.md @@ -38,12 +38,6 @@ export default async function createPlugin( builder.addEntityProvider( BitbucketServerEntityProvider.fromConfig(env.config, { logger: env.logger, - // optional: alternatively, use scheduler with schedule defined in app-config.yaml - schedule: env.scheduler.createScheduledTaskRunner({ - frequency: { minutes: 30 }, - timeout: { minutes: 3 }, - }), - // optional: alternatively, use schedule scheduler: env.scheduler, }), ); @@ -69,7 +63,7 @@ catalog: filters: # optional projectKey: '^apis-.*$' # optional; RegExp repoSlug: '^service-.*$' # optional; RegExp - schedule: # optional; same options as in TaskScheduleDefinition + schedule: # same options as in TaskScheduleDefinition # supports cron, ISO duration, "human duration" as used in code frequency: { minutes: 30 } # supports ISO duration, "human duration" as used in code @@ -87,7 +81,7 @@ catalog: Regular expression used to filter results based on the project key. - **`repoSlug`** _(optional)_: Regular expression used to filter results based on the repo slug. -- **`schedule`** _(optional)_: +- **`schedule`**: - **`frequency`**: How often you want the task to run. The system does its best to avoid overlapping invocations. - **`timeout`**: diff --git a/docs/integrations/gerrit/discovery.md b/docs/integrations/gerrit/discovery.md index 5d822effb5..ee843d2454 100644 --- a/docs/integrations/gerrit/discovery.md +++ b/docs/integrations/gerrit/discovery.md @@ -26,18 +26,11 @@ Then add the plugin to the plugin catalog `packages/backend/src/plugins/catalog. ```ts /* packages/backend/src/plugins/catalog.ts */ import { GerritEntityProvider } from '@backstage/plugin-catalog-backend-module-gerrit'; -import { Duration } from 'luxon'; const builder = await CatalogBuilder.create(env); /** ... other processors and/or providers ... */ builder.addEntityProvider( GerritEntityProvider.fromConfig(env.config, { logger: env.logger, - // optional: alternatively, use scheduler with schedule defined in app-config.yaml - schedule: env.scheduler.createScheduledTaskRunner({ - frequency: { minutes: 30 }, - timeout: { minutes: 3 }, - }), - // optional: alternatively, use schedule scheduler: env.scheduler, }), ); @@ -57,7 +50,7 @@ catalog: host: gerrit-your-company.com branch: master # Optional query: 'state=ACTIVE&prefix=webapps' - schedule: # optional; same options as in TaskScheduleDefinition + schedule: # supports cron, ISO duration, "human duration" as used in code frequency: { minutes: 30 } # supports ISO duration, "human duration" as used in code diff --git a/docs/integrations/github/discovery.md b/docs/integrations/github/discovery.md index 46d59cbf1b..3c3d90d6e9 100644 --- a/docs/integrations/github/discovery.md +++ b/docs/integrations/github/discovery.md @@ -40,12 +40,6 @@ export default async function createPlugin( builder.addEntityProvider( GithubEntityProvider.fromConfig(env.config, { logger: env.logger, - // optional: alternatively, use scheduler with schedule defined in app-config.yaml - schedule: env.scheduler.createScheduledTaskRunner({ - frequency: { minutes: 30 }, - timeout: { minutes: 3 }, - }), - // optional: alternatively, use schedule scheduler: env.scheduler, }), ); @@ -85,12 +79,6 @@ export default async function createPlugin( /* highlight-add-start */ const githubProvider = GithubEntityProvider.fromConfig(env.config, { logger: env.logger, - // optional: alternatively, use scheduler with schedule defined in app-config.yaml - schedule: env.scheduler.createScheduledTaskRunner({ - frequency: { minutes: 30 }, - timeout: { minutes: 3 }, - }), - // optional: alternatively, use schedule scheduler: env.scheduler, }); env.eventBroker.subscribe(githubProvider); @@ -122,7 +110,7 @@ catalog: filters: branch: 'main' # string repository: '.*' # Regex - schedule: # optional; same options as in TaskScheduleDefinition + schedule: # same options as in TaskScheduleDefinition # supports cron, ISO duration, "human duration" as used in code frequency: { minutes: 30 } # supports ISO duration, "human duration" as used in code @@ -213,7 +201,7 @@ This provider supports multiple organizations via unique provider IDs. Defaults to `false`. Due to limitations in the GitHub API's ability to query for repository objects, this option cannot be used in conjunction with wildcards in the `catalogPath`. -- **`schedule`** _(optional)_: +- **`schedule`**: - **`frequency`**: How often you want the task to run. The system does its best to avoid overlapping invocations. - **`timeout`**: @@ -229,13 +217,12 @@ GitHub [rate limits](https://docs.github.com/en/rest/overview/resources-in-the-r accounts). The snippet below refreshes the Backstage catalog data every 35 minutes, which issues an API request for each discovered location. If your requests are too frequent then you may get throttled by -rate limiting. You can change the refresh frequency of the catalog in your `packages/backend/src/plugins/catalog.ts` file: +rate limiting. You can change the refresh frequency of the catalog in your `app-config.yaml` file by controlling the `schedule`. -```typescript -schedule: env.scheduler.createScheduledTaskRunner({ - frequency: { minutes: 35 }, - timeout: { minutes: 30 }, -}), +```yaml +schedule: + frequency: { minutes: 35 } + timeout: { minutes: 3 } ``` More information about scheduling can be found on the [TaskScheduleDefinition](https://backstage.io/docs/reference/backend-tasks.taskscheduledefinition) page. From 01594ee027bcc32a62d56201122fe0a90d4672f0 Mon Sep 17 00:00:00 2001 From: Antonino Provenzano Date: Fri, 17 Nov 2023 13:46:12 +0100 Subject: [PATCH 004/275] Update docs/features/techdocs/how-to-guides.md Co-authored-by: Andre Wanlin <67169551+awanlin@users.noreply.github.com> Signed-off-by: Antonino Provenzano --- docs/features/techdocs/how-to-guides.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/techdocs/how-to-guides.md b/docs/features/techdocs/how-to-guides.md index 8415640569..a71e656226 100644 --- a/docs/features/techdocs/how-to-guides.md +++ b/docs/features/techdocs/how-to-guides.md @@ -516,7 +516,7 @@ theme: font: false ``` -note: The addition "name material" is necessary. Otherwise it will not work +> Note: The addition `name: material` is necessary. Otherwise it will not work ## How to enable iframes in TechDocs From fcc90e9d15d316ac4a6e45db53e8698463861947 Mon Sep 17 00:00:00 2001 From: Antonino Provenzano Date: Fri, 17 Nov 2023 15:09:13 +0100 Subject: [PATCH 005/275] Update accept.txt Added "Roboto" in file Signed-off-by: Antonino Provenzano --- .github/vale/Vocab/Backstage/accept.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/vale/Vocab/Backstage/accept.txt b/.github/vale/Vocab/Backstage/accept.txt index 73f6d56bb4..8a778fc5fe 100644 --- a/.github/vale/Vocab/Backstage/accept.txt +++ b/.github/vale/Vocab/Backstage/accept.txt @@ -323,6 +323,7 @@ reusability Reusability roadmaps rollbar +Roboto Rollbar Rollup routable From 286b6f90c3deea0e547c41defa2bb9e5e9096b76 Mon Sep 17 00:00:00 2001 From: Antonino Provenzano Date: Fri, 17 Nov 2023 15:13:31 +0100 Subject: [PATCH 006/275] Update how-to-guides.md Removed "note:". It was a mistake Signed-off-by: Antonino Provenzano --- docs/features/techdocs/how-to-guides.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/features/techdocs/how-to-guides.md b/docs/features/techdocs/how-to-guides.md index a71e656226..4a562dd1c0 100644 --- a/docs/features/techdocs/how-to-guides.md +++ b/docs/features/techdocs/how-to-guides.md @@ -483,8 +483,6 @@ plugins: - techdocs-core ``` -note: - 3. Create a `/docs` folder in the skeleton folder with at least an `index.md` file in it. From d2f5662985c347578b3b786b67a0f2ee396eaa60 Mon Sep 17 00:00:00 2001 From: dimisjim Date: Fri, 17 Nov 2023 15:45:10 +0100 Subject: [PATCH 007/275] fix query params + added changeset Signed-off-by: dimisjim --- .changeset/sweet-buckets-hunt.md | 5 +++++ .../src/components/ProjectDetailsPage/ProjectDetailsPage.tsx | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 .changeset/sweet-buckets-hunt.md diff --git a/.changeset/sweet-buckets-hunt.md b/.changeset/sweet-buckets-hunt.md new file mode 100644 index 0000000000..c8a7794457 --- /dev/null +++ b/.changeset/sweet-buckets-hunt.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-gcp-projects': patch +--- + +Fix query parameter for project details page which should point to projectId rather than project name diff --git a/plugins/gcp-projects/src/components/ProjectDetailsPage/ProjectDetailsPage.tsx b/plugins/gcp-projects/src/components/ProjectDetailsPage/ProjectDetailsPage.tsx index 364033ce73..8dea9fca8a 100644 --- a/plugins/gcp-projects/src/components/ProjectDetailsPage/ProjectDetailsPage.tsx +++ b/plugins/gcp-projects/src/components/ProjectDetailsPage/ProjectDetailsPage.tsx @@ -127,7 +127,7 @@ const DetailsPage = () => { {details?.name && ( + + ); + }, + }, }); diff --git a/packages/frontend-plugin-api/api-report.md b/packages/frontend-plugin-api/api-report.md index e8f4f16e97..e578c181fb 100644 --- a/packages/frontend-plugin-api/api-report.md +++ b/packages/frontend-plugin-api/api-report.md @@ -22,7 +22,6 @@ import { AuthProviderInfo } from '@backstage/core-plugin-api'; import { AuthRequestOptions } from '@backstage/core-plugin-api'; import { BackstageIdentityApi } from '@backstage/core-plugin-api'; import { BackstageIdentityResponse } from '@backstage/core-plugin-api'; -import { BackstagePlugin as BackstagePlugin_2 } from '@backstage/core-plugin-api'; import { BackstageUserIdentity } from '@backstage/core-plugin-api'; import { bitbucketAuthApiRef } from '@backstage/core-plugin-api'; import { bitbucketServerAuthApiRef } from '@backstage/core-plugin-api'; @@ -340,7 +339,7 @@ export const coreComponentsRefs: { // @public (undocumented) export type CoreErrorBoundaryFallbackComponent = ComponentType< PropsWithChildren<{ - plugin?: BackstagePlugin_2; + plugin?: BackstagePlugin; error: Error; resetError: () => void; }> diff --git a/packages/frontend-plugin-api/src/components/ErrorBoundary.tsx b/packages/frontend-plugin-api/src/components/ErrorBoundary.tsx index 1191b75a1d..e3765be386 100644 --- a/packages/frontend-plugin-api/src/components/ErrorBoundary.tsx +++ b/packages/frontend-plugin-api/src/components/ErrorBoundary.tsx @@ -15,34 +15,13 @@ */ import React, { Component, PropsWithChildren } from 'react'; -// TODO: Dependency on MUI should be removed from core packages -import { Button } from '@material-ui/core'; -import { ErrorPanel } from '@backstage/core-components'; import { BackstagePlugin } from '../wiring'; +import { CoreErrorBoundaryFallbackComponent } from '../types'; -type DefaultErrorBoundaryFallbackProps = PropsWithChildren<{ +type ErrorBoundaryProps = PropsWithChildren<{ plugin?: BackstagePlugin; - error: Error; - resetError: () => void; + fallback: CoreErrorBoundaryFallbackComponent; }>; - -const DefaultErrorBoundaryFallback = ({ - plugin, - error, - resetError, -}: DefaultErrorBoundaryFallbackProps) => { - const title = `Error in ${plugin?.id}`; - - return ( - - - - ); -}; - -type ErrorBoundaryProps = PropsWithChildren<{ plugin?: BackstagePlugin }>; type ErrorBoundaryState = { error?: Error }; /** @internal */ @@ -62,12 +41,11 @@ export class ErrorBoundary extends Component< render() { const { error } = this.state; - const { plugin, children } = this.props; + const { plugin, children, fallback: Fallback } = this.props; if (error) { - // TODO: use a configurable error boundary fallback return ( - - + {children} diff --git a/packages/frontend-plugin-api/src/types.ts b/packages/frontend-plugin-api/src/types.ts index f3f68c362c..3c79bcdf35 100644 --- a/packages/frontend-plugin-api/src/types.ts +++ b/packages/frontend-plugin-api/src/types.ts @@ -14,8 +14,8 @@ * limitations under the License. */ -import { BackstagePlugin } from '@backstage/core-plugin-api'; import { ComponentType, PropsWithChildren } from 'react'; +import { BackstagePlugin } from './wiring'; // TODO(Rugvip): This might be a quite useful utility type, maybe add to @backstage/types? /** From e5b00a94e648290eeb3e08e3127b3944dcf53428 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Thu, 30 Nov 2023 13:08:45 +0100 Subject: [PATCH 033/275] refactor: use unknown on component ref type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Philipp Hugenroth Co-authored-by: Fredrik Adelöw Co-authored-by: Patrik Oldsberg Signed-off-by: Camila Belo --- .../ComponentsApi/ComponentsApi.ts | 5 +- packages/frontend-plugin-api/api-report.md | 56 +++++++++---------- .../src/apis/definitions/ComponentsApi.ts | 3 +- .../src/components/ComponentRef.tsx | 20 +++---- .../src/components/ErrorBoundary.tsx | 6 +- .../extensions/createComponentExtension.tsx | 22 ++++---- packages/frontend-plugin-api/src/index.ts | 8 +-- packages/frontend-plugin-api/src/types.ts | 30 ++++------ .../src/wiring/coreExtensionData.ts | 4 +- 9 files changed, 75 insertions(+), 79 deletions(-) diff --git a/packages/frontend-app-api/src/apis/implementations/ComponentsApi/ComponentsApi.ts b/packages/frontend-app-api/src/apis/implementations/ComponentsApi/ComponentsApi.ts index 50d125e4ab..4d8bc47e24 100644 --- a/packages/frontend-app-api/src/apis/implementations/ComponentsApi/ComponentsApi.ts +++ b/packages/frontend-app-api/src/apis/implementations/ComponentsApi/ComponentsApi.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +import { ComponentType } from 'react'; import { ComponentRef, ComponentsApi } from '@backstage/frontend-plugin-api'; /** @@ -22,13 +23,13 @@ import { ComponentRef, ComponentsApi } from '@backstage/frontend-plugin-api'; * @internal */ export class DefaultComponentsApi implements ComponentsApi { - #components: Map, any>; + #components: Map, ComponentType>; constructor(components: Map, any>) { this.#components = components; } - getComponent(ref: ComponentRef): T { + getComponent(ref: ComponentRef): ComponentType { const impl = this.#components.get(ref); if (!impl) { throw new Error(`No implementation found for component ref ${ref}`); diff --git a/packages/frontend-plugin-api/api-report.md b/packages/frontend-plugin-api/api-report.md index e578c181fb..7342558560 100644 --- a/packages/frontend-plugin-api/api-report.md +++ b/packages/frontend-plugin-api/api-report.md @@ -286,7 +286,7 @@ export type CommonAnalyticsContext = { }; // @public (undocumented) -export type ComponentRef = { +export type ComponentRef = { id: string; T: T; }; @@ -294,7 +294,7 @@ export type ComponentRef = { // @public export interface ComponentsApi { // (undocumented) - getComponent(ref: ComponentRef): T; + getComponent(ref: ComponentRef): ComponentType; } // @public @@ -321,29 +321,29 @@ export interface ConfigurableExtensionDataRef< } // @public (undocumented) -export type CoreBootErrorPageComponent = ComponentType< - PropsWithChildren<{ - step: 'load-config' | 'load-chunk'; - error: Error; - }> ->; +export type CoreBootErrorPageProps = PropsWithChildren<{ + step: 'load-config' | 'load-chunk'; + error: Error; +}>; // @public (undocumented) export const coreComponentsRefs: { - progress: ComponentRef; - bootErrorPage: ComponentRef; - notFoundErrorPage: ComponentRef; - errorBoundaryFallback: ComponentRef; + progress: ComponentRef<{ + children?: ReactNode; + }>; + bootErrorPage: ComponentRef; + notFoundErrorPage: ComponentRef<{ + children?: ReactNode; + }>; + errorBoundaryFallback: ComponentRef; }; // @public (undocumented) -export type CoreErrorBoundaryFallbackComponent = ComponentType< - PropsWithChildren<{ - plugin?: BackstagePlugin; - error: Error; - resetError: () => void; - }> ->; +export type CoreErrorBoundaryFallbackProps = PropsWithChildren<{ + plugin?: BackstagePlugin; + error: Error; + resetError: () => void; +}>; // @public (undocumented) export const coreExtensionData: { @@ -356,20 +356,18 @@ export const coreExtensionData: { logoElements: ConfigurableExtensionDataRef; component: ConfigurableExtensionDataRef< { - ref: ComponentRef>; - impl: ComponentType; + ref: ComponentRef; + impl: ComponentType; }, {} >; }; // @public (undocumented) -export type CoreNotFoundErrorPageComponent = ComponentType< - PropsWithChildren<{}> ->; +export type CoreNotFoundErrorPageProps = PropsWithChildren<{}>; // @public (undocumented) -export type CoreProgressComponent = ComponentType>; +export type CoreProgressProps = PropsWithChildren<{}>; // @public (undocumented) export function createApiExtension< @@ -399,11 +397,11 @@ export { createApiRef }; // @public (undocumented) export function createComponentExtension< - TRef extends ComponentRef, + TProps extends {}, TConfig extends {}, TInputs extends AnyExtensionInputMap, >(options: { - ref: TRef; + ref: ComponentRef; name?: string; disabled?: boolean; inputs?: TInputs; @@ -413,13 +411,13 @@ export function createComponentExtension< lazy: (values: { config: TConfig; inputs: Expand>; - }) => Promise; + }) => Promise>; } | { sync: (values: { config: TConfig; inputs: Expand>; - }) => TRef['T']; + }) => ComponentType; }; }): ExtensionDefinition; diff --git a/packages/frontend-plugin-api/src/apis/definitions/ComponentsApi.ts b/packages/frontend-plugin-api/src/apis/definitions/ComponentsApi.ts index b55ed96549..dee17e7d97 100644 --- a/packages/frontend-plugin-api/src/apis/definitions/ComponentsApi.ts +++ b/packages/frontend-plugin-api/src/apis/definitions/ComponentsApi.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +import { ComponentType } from 'react'; import { createApiRef } from '@backstage/core-plugin-api'; import { ComponentRef } from '../../components'; @@ -24,7 +25,7 @@ import { ComponentRef } from '../../components'; */ export interface ComponentsApi { // TODO: Should component refs also provide the default implementation so that we're guaranteed to get a component? - getComponent(ref: ComponentRef): T; + getComponent(ref: ComponentRef): ComponentType; } /** diff --git a/packages/frontend-plugin-api/src/components/ComponentRef.tsx b/packages/frontend-plugin-api/src/components/ComponentRef.tsx index d096fa34f3..dd2e65a61f 100644 --- a/packages/frontend-plugin-api/src/components/ComponentRef.tsx +++ b/packages/frontend-plugin-api/src/components/ComponentRef.tsx @@ -15,20 +15,20 @@ */ import { - CoreBootErrorPageComponent, - CoreErrorBoundaryFallbackComponent, - CoreNotFoundErrorPageComponent, - CoreProgressComponent, + CoreBootErrorPageProps, + CoreErrorBoundaryFallbackProps, + CoreNotFoundErrorPageProps, + CoreProgressProps, } from '../types'; /** @public */ -export type ComponentRef = { +export type ComponentRef = { id: string; T: T; }; /** @public */ -export function createComponentRef(options: { +export function createComponentRef(options: { id: string; }): ComponentRef { const { id } = options; @@ -37,22 +37,22 @@ export function createComponentRef(options: { } as ComponentRef; } -const coreProgressComponentRef = createComponentRef({ +const coreProgressComponentRef = createComponentRef({ id: 'core.components.progress', }); const coreBootErrorPageComponentRef = - createComponentRef({ + createComponentRef({ id: 'core.components.bootErrorPage', }); const coreNotFoundErrorPageComponentRef = - createComponentRef({ + createComponentRef({ id: 'core.components.notFoundErrorPage', }); const coreErrorBoundaryFallbackComponentRef = - createComponentRef({ + createComponentRef({ id: 'core.components.errorBoundaryFallback', }); diff --git a/packages/frontend-plugin-api/src/components/ErrorBoundary.tsx b/packages/frontend-plugin-api/src/components/ErrorBoundary.tsx index e3765be386..be988dc14f 100644 --- a/packages/frontend-plugin-api/src/components/ErrorBoundary.tsx +++ b/packages/frontend-plugin-api/src/components/ErrorBoundary.tsx @@ -14,13 +14,13 @@ * limitations under the License. */ -import React, { Component, PropsWithChildren } from 'react'; +import React, { Component, ComponentType, PropsWithChildren } from 'react'; import { BackstagePlugin } from '../wiring'; -import { CoreErrorBoundaryFallbackComponent } from '../types'; +import { CoreErrorBoundaryFallbackProps } from '../types'; type ErrorBoundaryProps = PropsWithChildren<{ plugin?: BackstagePlugin; - fallback: CoreErrorBoundaryFallbackComponent; + fallback: ComponentType; }>; type ErrorBoundaryState = { error?: Error }; diff --git a/packages/frontend-plugin-api/src/extensions/createComponentExtension.tsx b/packages/frontend-plugin-api/src/extensions/createComponentExtension.tsx index 601ee81d11..816dee6054 100644 --- a/packages/frontend-plugin-api/src/extensions/createComponentExtension.tsx +++ b/packages/frontend-plugin-api/src/extensions/createComponentExtension.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import React, { lazy } from 'react'; +import React, { lazy, ComponentType } from 'react'; import { AnyExtensionInputMap, ResolvedExtensionInputs, @@ -27,11 +27,11 @@ import { ExtensionBoundary, ComponentRef } from '../components'; /** @public */ export function createComponentExtension< - TRef extends ComponentRef, + TProps extends {}, TConfig extends {}, TInputs extends AnyExtensionInputMap, >(options: { - ref: TRef; + ref: ComponentRef; name?: string; disabled?: boolean; inputs?: TInputs; @@ -41,13 +41,13 @@ export function createComponentExtension< lazy: (values: { config: TConfig; inputs: Expand>; - }) => Promise; + }) => Promise>; } | { sync: (values: { config: TConfig; inputs: Expand>; - }) => TRef['T']; + }) => ComponentType; }; }) { return createExtension({ @@ -62,15 +62,17 @@ export function createComponentExtension< component: coreExtensionData.component, }, factory({ config, inputs, node }) { - let ExtensionComponent: TRef['T']; + let ExtensionComponent: ComponentType; if ('sync' in options.component) { ExtensionComponent = options.component.sync({ config, inputs }); } else { - const loader = options.component.lazy({ config, inputs }); + const lazyLoader = options.component.lazy; ExtensionComponent = lazy(() => - loader.then(component => ({ default: component })), - ); + lazyLoader({ config, inputs }).then(component => ({ + default: component, + })), + ) as unknown as ComponentType; } return { @@ -78,7 +80,7 @@ export function createComponentExtension< ref: options.ref, impl: props => ( - + ), }, diff --git a/packages/frontend-plugin-api/src/index.ts b/packages/frontend-plugin-api/src/index.ts index a38a7991fb..04cbddd336 100644 --- a/packages/frontend-plugin-api/src/index.ts +++ b/packages/frontend-plugin-api/src/index.ts @@ -31,8 +31,8 @@ export * from './apis/system'; export * from './wiring'; export type { - CoreProgressComponent, - CoreBootErrorPageComponent, - CoreNotFoundErrorPageComponent, - CoreErrorBoundaryFallbackComponent, + CoreProgressProps, + CoreBootErrorPageProps, + CoreNotFoundErrorPageProps, + CoreErrorBoundaryFallbackProps, } from './types'; diff --git a/packages/frontend-plugin-api/src/types.ts b/packages/frontend-plugin-api/src/types.ts index 3c79bcdf35..a69c483b5c 100644 --- a/packages/frontend-plugin-api/src/types.ts +++ b/packages/frontend-plugin-api/src/types.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { ComponentType, PropsWithChildren } from 'react'; +import { PropsWithChildren } from 'react'; import { BackstagePlugin } from './wiring'; // TODO(Rugvip): This might be a quite useful utility type, maybe add to @backstage/types? @@ -25,26 +25,20 @@ import { BackstagePlugin } from './wiring'; export type Expand = T extends infer O ? { [K in keyof O]: O[K] } : never; /** @public */ -export type CoreProgressComponent = ComponentType>; +export type CoreProgressProps = PropsWithChildren<{}>; /** @public */ -export type CoreBootErrorPageComponent = ComponentType< - PropsWithChildren<{ - step: 'load-config' | 'load-chunk'; - error: Error; - }> ->; +export type CoreBootErrorPageProps = PropsWithChildren<{ + step: 'load-config' | 'load-chunk'; + error: Error; +}>; /** @public */ -export type CoreNotFoundErrorPageComponent = ComponentType< - PropsWithChildren<{}> ->; +export type CoreNotFoundErrorPageProps = PropsWithChildren<{}>; /** @public */ -export type CoreErrorBoundaryFallbackComponent = ComponentType< - PropsWithChildren<{ - plugin?: BackstagePlugin; - error: Error; - resetError: () => void; - }> ->; +export type CoreErrorBoundaryFallbackProps = PropsWithChildren<{ + plugin?: BackstagePlugin; + error: Error; + resetError: () => void; +}>; diff --git a/packages/frontend-plugin-api/src/wiring/coreExtensionData.ts b/packages/frontend-plugin-api/src/wiring/coreExtensionData.ts index 9bdb4b23eb..47a77414a0 100644 --- a/packages/frontend-plugin-api/src/wiring/coreExtensionData.ts +++ b/packages/frontend-plugin-api/src/wiring/coreExtensionData.ts @@ -47,7 +47,7 @@ export const coreExtensionData = { theme: createExtensionDataRef('core.theme'), logoElements: createExtensionDataRef('core.logos'), component: createExtensionDataRef<{ - ref: ComponentRef>; - impl: ComponentType; + ref: ComponentRef; + impl: ComponentType; }>('component.ref'), }; From de595c955c18978a45aa53464f0ed99337072214 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Thu, 30 Nov 2023 16:19:30 +0100 Subject: [PATCH 034/275] refactor: use progress component on extention error boundary Signed-off-by: Camila Belo --- .../frontend-plugin-api/src/components/ExtensionBoundary.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/frontend-plugin-api/src/components/ExtensionBoundary.tsx b/packages/frontend-plugin-api/src/components/ExtensionBoundary.tsx index 1e946efba9..d830f665f0 100644 --- a/packages/frontend-plugin-api/src/components/ExtensionBoundary.tsx +++ b/packages/frontend-plugin-api/src/components/ExtensionBoundary.tsx @@ -64,6 +64,7 @@ export function ExtensionBoundary(props: ExtensionBoundaryProps) { const componentsApi = useApi(componentsApiRef); const plugin = node.spec.source; + const Progress = componentsApi.getComponent(coreComponentsRefs.progress); const fallback = componentsApi.getComponent( coreComponentsRefs.errorBoundaryFallback, ); @@ -75,7 +76,7 @@ export function ExtensionBoundary(props: ExtensionBoundaryProps) { }; return ( - + }> {children} From b7adf24bf9aceada423c478ed38bc57f61813ec5 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Thu, 30 Nov 2023 15:33:19 +0100 Subject: [PATCH 035/275] docs: add changelog files Signed-off-by: Camila Belo --- .changeset/brave-beers-happen.md | 5 +++++ .changeset/good-wolves-leave.md | 5 +++++ .changeset/sharp-dingos-learn.md | 5 +++++ 3 files changed, 15 insertions(+) create mode 100644 .changeset/brave-beers-happen.md create mode 100644 .changeset/good-wolves-leave.md create mode 100644 .changeset/sharp-dingos-learn.md diff --git a/.changeset/brave-beers-happen.md b/.changeset/brave-beers-happen.md new file mode 100644 index 0000000000..8a16ed4824 --- /dev/null +++ b/.changeset/brave-beers-happen.md @@ -0,0 +1,5 @@ +--- +'@backstage/frontend-plugin-api': patch +--- + +**_BREAKING_**: update alpha component ref type to be more specific than any and use new plugin type for error boundary component extensions. diff --git a/.changeset/good-wolves-leave.md b/.changeset/good-wolves-leave.md new file mode 100644 index 0000000000..c2cde8bfed --- /dev/null +++ b/.changeset/good-wolves-leave.md @@ -0,0 +1,5 @@ +--- +'@backstage/frontend-app-api': patch +--- + +**_BREAKING_**: Use the new plugin type for error boundary components. diff --git a/.changeset/sharp-dingos-learn.md b/.changeset/sharp-dingos-learn.md new file mode 100644 index 0000000000..9dbb7ed8f4 --- /dev/null +++ b/.changeset/sharp-dingos-learn.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-compat-api': patch +--- + +**_BREAKING_**: delete alpha DI compatibility helper for components, migrating components should be simple without an helper. From e91c19d00670ba73e8699a4bbc0e2438f4bc63da Mon Sep 17 00:00:00 2001 From: Philipp Hugenroth Date: Fri, 1 Dec 2023 14:52:39 +0100 Subject: [PATCH 036/275] Fix MuiPaper background color in v5 default dark mode Signed-off-by: Philipp Hugenroth --- packages/theme/src/v5/defaultComponentThemes.ts | 3 +++ plugins/user-settings/package.json | 1 + .../src/components/General/UserSettingsIdentityCard.tsx | 6 +++--- yarn.lock | 9 +++++---- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/packages/theme/src/v5/defaultComponentThemes.ts b/packages/theme/src/v5/defaultComponentThemes.ts index e484300818..60caa47e90 100644 --- a/packages/theme/src/v5/defaultComponentThemes.ts +++ b/packages/theme/src/v5/defaultComponentThemes.ts @@ -239,4 +239,7 @@ export const defaultComponentThemes: ThemeOptions['components'] = { underline: 'hover', }, }, + MuiPaper: { + styleOverrides: { root: { backgroundImage: 'unset' } }, + }, }; diff --git a/plugins/user-settings/package.json b/plugins/user-settings/package.json index c25cff5ede..37d93ed559 100644 --- a/plugins/user-settings/package.json +++ b/plugins/user-settings/package.json @@ -58,6 +58,7 @@ "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.61", + "@mui/material": "^5.14.19", "@types/react": "^16.13.1 || ^17.0.0", "react-use": "^17.2.4", "zen-observable": "^0.10.0" diff --git a/plugins/user-settings/src/components/General/UserSettingsIdentityCard.tsx b/plugins/user-settings/src/components/General/UserSettingsIdentityCard.tsx index d8d3f677aa..2bdcf88c17 100644 --- a/plugins/user-settings/src/components/General/UserSettingsIdentityCard.tsx +++ b/plugins/user-settings/src/components/General/UserSettingsIdentityCard.tsx @@ -14,10 +14,10 @@ * limitations under the License. */ -import { InfoCard } from '@backstage/core-components'; import { EntityRefLinks } from '@backstage/plugin-catalog-react'; import Grid from '@material-ui/core/Grid'; import Typography from '@material-ui/core/Typography'; +import Card from '@mui/material/Card'; import React from 'react'; import { useUserProfile } from '../useUserProfileInfo'; @@ -48,7 +48,7 @@ const Contents = () => { /** @public */ export const UserSettingsIdentityCard = () => ( - + - + ); diff --git a/yarn.lock b/yarn.lock index 0d8d076b45..3f3beb51e6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3916,7 +3916,7 @@ __metadata: languageName: node linkType: hard -"@backstage/core-components@npm:^0.13.7, @backstage/core-components@npm:^0.13.8": +"@backstage/core-components@npm:^0.13.8": version: 0.13.8 resolution: "@backstage/core-components@npm:0.13.8" dependencies: @@ -4042,7 +4042,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/core-plugin-api@npm:^1.3.0, @backstage/core-plugin-api@npm:^1.5.0, @backstage/core-plugin-api@npm:^1.7.0, @backstage/core-plugin-api@npm:^1.8.0": +"@backstage/core-plugin-api@npm:^1.3.0, @backstage/core-plugin-api@npm:^1.5.0, @backstage/core-plugin-api@npm:^1.8.0": version: 1.8.0 resolution: "@backstage/core-plugin-api@npm:1.8.0" dependencies: @@ -5950,7 +5950,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-catalog-react@npm:^1.2.4, @backstage/plugin-catalog-react@npm:^1.8.5, @backstage/plugin-catalog-react@npm:^1.9.1": +"@backstage/plugin-catalog-react@npm:^1.2.4, @backstage/plugin-catalog-react@npm:^1.9.1": version: 1.9.1 resolution: "@backstage/plugin-catalog-react@npm:1.9.1" dependencies: @@ -9948,6 +9948,7 @@ __metadata: "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 + "@mui/material": ^5.14.19 "@testing-library/dom": ^9.0.0 "@testing-library/jest-dom": ^6.0.0 "@testing-library/react": ^14.0.0 @@ -13326,7 +13327,7 @@ __metadata: languageName: node linkType: hard -"@mui/material@npm:^5.12.2": +"@mui/material@npm:^5.12.2, @mui/material@npm:^5.14.19": version: 5.14.19 resolution: "@mui/material@npm:5.14.19" dependencies: From cd0dd4c3ee9bf1128f600aa3a4c11d3c5325a750 Mon Sep 17 00:00:00 2001 From: Philipp Hugenroth Date: Fri, 1 Dec 2023 14:59:28 +0100 Subject: [PATCH 037/275] Add changeset & adjust to relevant changes only Signed-off-by: Philipp Hugenroth --- .changeset/dirty-turkeys-reflect.md | 5 +++++ plugins/user-settings/package.json | 1 - .../src/components/General/UserSettingsIdentityCard.tsx | 6 +++--- yarn.lock | 3 +-- 4 files changed, 9 insertions(+), 6 deletions(-) create mode 100644 .changeset/dirty-turkeys-reflect.md diff --git a/.changeset/dirty-turkeys-reflect.md b/.changeset/dirty-turkeys-reflect.md new file mode 100644 index 0000000000..eac601f75c --- /dev/null +++ b/.changeset/dirty-turkeys-reflect.md @@ -0,0 +1,5 @@ +--- +'@backstage/theme': patch +--- + +Align Material UI v5 `Paper` component background color in dark mode to v4. diff --git a/plugins/user-settings/package.json b/plugins/user-settings/package.json index 37d93ed559..c25cff5ede 100644 --- a/plugins/user-settings/package.json +++ b/plugins/user-settings/package.json @@ -58,7 +58,6 @@ "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.61", - "@mui/material": "^5.14.19", "@types/react": "^16.13.1 || ^17.0.0", "react-use": "^17.2.4", "zen-observable": "^0.10.0" diff --git a/plugins/user-settings/src/components/General/UserSettingsIdentityCard.tsx b/plugins/user-settings/src/components/General/UserSettingsIdentityCard.tsx index 2bdcf88c17..d8d3f677aa 100644 --- a/plugins/user-settings/src/components/General/UserSettingsIdentityCard.tsx +++ b/plugins/user-settings/src/components/General/UserSettingsIdentityCard.tsx @@ -14,10 +14,10 @@ * limitations under the License. */ +import { InfoCard } from '@backstage/core-components'; import { EntityRefLinks } from '@backstage/plugin-catalog-react'; import Grid from '@material-ui/core/Grid'; import Typography from '@material-ui/core/Typography'; -import Card from '@mui/material/Card'; import React from 'react'; import { useUserProfile } from '../useUserProfileInfo'; @@ -48,7 +48,7 @@ const Contents = () => { /** @public */ export const UserSettingsIdentityCard = () => ( - + - + ); diff --git a/yarn.lock b/yarn.lock index 3f3beb51e6..9759cf8787 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9948,7 +9948,6 @@ __metadata: "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 - "@mui/material": ^5.14.19 "@testing-library/dom": ^9.0.0 "@testing-library/jest-dom": ^6.0.0 "@testing-library/react": ^14.0.0 @@ -13327,7 +13326,7 @@ __metadata: languageName: node linkType: hard -"@mui/material@npm:^5.12.2, @mui/material@npm:^5.14.19": +"@mui/material@npm:^5.12.2": version: 5.14.19 resolution: "@mui/material@npm:5.14.19" dependencies: From 24f5a8567d98aa1cb8fc2c953b65a8c8efdf2a8f Mon Sep 17 00:00:00 2001 From: Mitchell Hentges Date: Fri, 1 Dec 2023 16:17:52 +0100 Subject: [PATCH 038/275] Add "path" to `TransformFunc` context We have a use case where the transform we're applying to a value _depends_ on where that value sits in the object tree. `filterPath` seemed better to expose that `visibilityPath` because: * JQ-style paths with `.` as separate are more common, and are supported by `lodash`'s `get()` function. * For array items, `visibilityPath` doesn't include the array index Signed-off-by: Mitchell Hentges --- .changeset/eighty-phones-peel.md | 5 +++++ packages/config-loader/api-report.md | 1 + packages/config-loader/src/schema/filtering.ts | 2 +- packages/config-loader/src/schema/types.ts | 13 ++++++++++++- 4 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 .changeset/eighty-phones-peel.md diff --git a/.changeset/eighty-phones-peel.md b/.changeset/eighty-phones-peel.md new file mode 100644 index 0000000000..954553427a --- /dev/null +++ b/.changeset/eighty-phones-peel.md @@ -0,0 +1,5 @@ +--- +'@backstage/config-loader': minor +--- + +Add "path" to `TransformFunc` context diff --git a/packages/config-loader/api-report.md b/packages/config-loader/api-report.md index 9f55a27bf7..66572dd960 100644 --- a/packages/config-loader/api-report.md +++ b/packages/config-loader/api-report.md @@ -274,6 +274,7 @@ export type TransformFunc = ( value: T, context: { visibility: ConfigVisibility; + path: string; }, ) => T | undefined; ``` diff --git a/packages/config-loader/src/schema/filtering.ts b/packages/config-loader/src/schema/filtering.ts index 1b7bbf43c1..9c1c2fbda5 100644 --- a/packages/config-loader/src/schema/filtering.ts +++ b/packages/config-loader/src/schema/filtering.ts @@ -68,7 +68,7 @@ export function filterByVisibility( if (typeof jsonVal !== 'object') { if (isVisible) { if (transformFunc) { - return transformFunc(jsonVal, { visibility }); + return transformFunc(jsonVal, { visibility, path: filterPath }); } return jsonVal; } diff --git a/packages/config-loader/src/schema/types.ts b/packages/config-loader/src/schema/types.ts index dc8da64038..8f679c93fc 100644 --- a/packages/config-loader/src/schema/types.ts +++ b/packages/config-loader/src/schema/types.ts @@ -105,11 +105,22 @@ export type ValidationFunc = (configs: AppConfig[]) => ValidationResult; /** * A function used to transform primitive configuration values. * + * The "path" in the context is a JQ-style path to the current value from + * within the original object passed to filterByVisibility(). + * For example, "field.list[2]" would refer to: + * \{ + * field: [ + * "foo", + * "bar", + * "baz" -- this one + * ] + * \} + * * @public */ export type TransformFunc = ( value: T, - context: { visibility: ConfigVisibility }, + context: { visibility: ConfigVisibility; path: string }, ) => T | undefined; /** From c70e4f52eba4315bd965af98a1c19b3ea2371bfa Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Mon, 27 Nov 2023 18:35:41 -0600 Subject: [PATCH 039/275] Added multi-org support Signed-off-by: Andre Wanlin --- .changeset/khaki-singers-film.md | 7 ++ plugins/azure-devops-backend/api-report.md | 23 +++++- .../src/api/AzureDevOpsApi.ts | 73 +++++++++++++++---- .../src/service/router.ts | 39 ++++++++-- plugins/azure-devops-common/api-report.md | 4 + plugins/azure-devops-common/src/types.ts | 2 + plugins/azure-devops/api-report.md | 16 ++++ .../azure-devops/src/api/AzureDevOpsApi.ts | 8 ++ .../azure-devops/src/api/AzureDevOpsClient.ts | 44 ++++++++++- .../azure-devops/src/hooks/useBuildRuns.ts | 5 +- plugins/azure-devops/src/hooks/useGitTags.ts | 4 +- .../azure-devops/src/hooks/usePullRequests.ts | 4 +- plugins/azure-devops/src/hooks/useReadme.ts | 4 +- 13 files changed, 202 insertions(+), 31 deletions(-) create mode 100644 .changeset/khaki-singers-film.md diff --git a/.changeset/khaki-singers-film.md b/.changeset/khaki-singers-film.md new file mode 100644 index 0000000000..0dd34f9c49 --- /dev/null +++ b/.changeset/khaki-singers-film.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-azure-devops-backend': patch +'@backstage/plugin-azure-devops-common': patch +'@backstage/plugin-azure-devops': patch +--- + +Added multi-org support diff --git a/plugins/azure-devops-backend/api-report.md b/plugins/azure-devops-backend/api-report.md index ac12f85131..6dead7f11b 100644 --- a/plugins/azure-devops-backend/api-report.md +++ b/plugins/azure-devops-backend/api-report.md @@ -60,12 +60,16 @@ export class AzureDevOpsApi { getBuildDefinitions( projectName: string, definitionName: string, + host?: string, + org?: string, ): Promise; // (undocumented) getBuildList( projectName: string, repoId: string, top: number, + host?: string, + org?: string, ): Promise; // (undocumented) getBuildRuns( @@ -73,6 +77,8 @@ export class AzureDevOpsApi { top: number, repoName?: string, definitionName?: string, + host?: string, + org?: string, ): Promise; // (undocumented) getBuilds( @@ -80,6 +86,8 @@ export class AzureDevOpsApi { top: number, repoId?: string, definitions?: number[], + host?: string, + org?: string, ): Promise; // (undocumented) getDashboardPullRequests( @@ -90,16 +98,25 @@ export class AzureDevOpsApi { getGitRepository( projectName: string, repoName: string, + host?: string, + org?: string, ): Promise; // (undocumented) - getGitTags(projectName: string, repoName: string): Promise; + getGitTags( + projectName: string, + repoName: string, + host?: string, + org?: string, + ): Promise; // (undocumented) - getProjects(): Promise; + getProjects(host?: string, org?: string): Promise; // (undocumented) getPullRequests( projectName: string, repoName: string, options: PullRequestOptions, + host?: string, + org?: string, ): Promise; // (undocumented) getReadme( @@ -116,6 +133,8 @@ export class AzureDevOpsApi { projectName: string, repoName: string, top: number, + host?: string, + org?: string, ): Promise; // (undocumented) getTeamMembers(options: { diff --git a/plugins/azure-devops-backend/src/api/AzureDevOpsApi.ts b/plugins/azure-devops-backend/src/api/AzureDevOpsApi.ts index 6765b54c05..3900882940 100644 --- a/plugins/azure-devops-backend/src/api/AzureDevOpsApi.ts +++ b/plugins/azure-devops-backend/src/api/AzureDevOpsApi.ts @@ -130,8 +130,8 @@ export class AzureDevOpsApi { return webApi; } - public async getProjects(): Promise { - const webApi = await this.getWebApi(); + public async getProjects(host?: string, org?: string): Promise { + const webApi = await this.getWebApi(host, org); const client = await webApi.getCoreApi(); const projectList: TeamProjectReference[] = await client.getProjects(); @@ -149,12 +149,14 @@ export class AzureDevOpsApi { public async getGitRepository( projectName: string, repoName: string, + host?: string, + org?: string, ): Promise { this.logger?.debug( `Calling Azure DevOps REST API, getting Repository ${repoName} for Project ${projectName}`, ); - const webApi = await this.getWebApi(); + const webApi = await this.getWebApi(host, org); const client = await webApi.getGitApi(); return client.getRepository(repoName, projectName); } @@ -163,12 +165,14 @@ export class AzureDevOpsApi { projectName: string, repoId: string, top: number, + host?: string, + org?: string, ): Promise { this.logger?.debug( `Calling Azure DevOps REST API, getting up to ${top} Builds for Repository Id ${repoId} for Project ${projectName}`, ); - const webApi = await this.getWebApi(); + const webApi = await this.getWebApi(host, org); const client = await webApi.getBuildApi(); return client.getBuilds( projectName, @@ -199,16 +203,25 @@ export class AzureDevOpsApi { projectName: string, repoName: string, top: number, + host?: string, + org?: string, ) { this.logger?.debug( `Calling Azure DevOps REST API, getting up to ${top} Builds for Repository ${repoName} for Project ${projectName}`, ); - const gitRepository = await this.getGitRepository(projectName, repoName); + const gitRepository = await this.getGitRepository( + projectName, + repoName, + host, + org, + ); const buildList = await this.getBuildList( projectName, gitRepository.id as string, top, + host, + org, ); const repoBuilds: RepoBuild[] = buildList.map(build => { @@ -221,13 +234,20 @@ export class AzureDevOpsApi { public async getGitTags( projectName: string, repoName: string, + host?: string, + org?: string, ): Promise { this.logger?.debug( `Calling Azure DevOps REST API, getting Git Tags for Repository ${repoName} for Project ${projectName}`, ); - const gitRepository = await this.getGitRepository(projectName, repoName); - const webApi = await this.getWebApi(); + const gitRepository = await this.getGitRepository( + projectName, + repoName, + host, + org, + ); + const webApi = await this.getWebApi(host, org); const client = await webApi.getGitApi(); const tagRefs: GitRef[] = await client.getRefs( gitRepository.id as string, @@ -256,13 +276,20 @@ export class AzureDevOpsApi { projectName: string, repoName: string, options: PullRequestOptions, + host?: string, + org?: string, ): Promise { this.logger?.debug( `Calling Azure DevOps REST API, getting up to ${options.top} Pull Requests for Repository ${repoName} for Project ${projectName}`, ); - const gitRepository = await this.getGitRepository(projectName, repoName); - const webApi = await this.getWebApi(); + const gitRepository = await this.getGitRepository( + projectName, + repoName, + host, + org, + ); + const webApi = await this.getWebApi(host, org); const client = await webApi.getGitApi(); const searchCriteria: GitPullRequestSearchCriteria = { status: options.status, @@ -397,12 +424,14 @@ export class AzureDevOpsApi { public async getBuildDefinitions( projectName: string, definitionName: string, + host?: string, + org?: string, ): Promise { this.logger?.debug( `Calling Azure DevOps REST API, getting Build Definitions for ${definitionName} in Project ${projectName}`, ); - const webApi = await this.getWebApi(); + const webApi = await this.getWebApi(host, org); const client = await webApi.getBuildApi(); return client.getDefinitions(projectName, definitionName); } @@ -412,12 +441,14 @@ export class AzureDevOpsApi { top: number, repoId?: string, definitions?: number[], + host?: string, + org?: string, ): Promise { this.logger?.debug( `Calling Azure DevOps REST API, getting up to ${top} Builds for Repository Id ${repoId} for Project ${projectName}`, ); - const webApi = await this.getWebApi(); + const webApi = await this.getWebApi(host, org); const client = await webApi.getBuildApi(); return client.getBuilds( projectName, @@ -449,12 +480,19 @@ export class AzureDevOpsApi { top: number, repoName?: string, definitionName?: string, + host?: string, + org?: string, ) { let repoId: string | undefined; let definitions: number[] | undefined; if (repoName) { - const gitRepository = await this.getGitRepository(projectName, repoName); + const gitRepository = await this.getGitRepository( + projectName, + repoName, + host, + org, + ); repoId = gitRepository.id; } @@ -462,13 +500,22 @@ export class AzureDevOpsApi { const buildDefinitions = await this.getBuildDefinitions( projectName, definitionName, + host, + org, ); definitions = buildDefinitions .map(bd => bd.id) .filter((bd): bd is number => Boolean(bd)); } - const builds = await this.getBuilds(projectName, top, repoId, definitions); + const builds = await this.getBuilds( + projectName, + top, + repoId, + definitions, + host, + org, + ); const buildRuns: BuildRun[] = builds.map(mappedBuildRun); diff --git a/plugins/azure-devops-backend/src/service/router.ts b/plugins/azure-devops-backend/src/service/router.ts index 9fc762f1a7..9a71c8f03d 100644 --- a/plugins/azure-devops-backend/src/service/router.ts +++ b/plugins/azure-devops-backend/src/service/router.ts @@ -75,10 +75,14 @@ export async function createRouter( router.get('/builds/:projectName/:repoId', async (req, res) => { const { projectName, repoId } = req.params; const top = req.query.top ? Number(req.query.top) : DEFAULT_TOP; + const host = req.query.host?.toString(); + const org = req.query.org?.toString(); const buildList = await azureDevOpsApi.getBuildList( projectName, repoId, top, + host, + org, ); res.status(200).json(buildList); }); @@ -87,11 +91,14 @@ export async function createRouter( const { projectName, repoName } = req.params; const top = req.query.top ? Number(req.query.top) : DEFAULT_TOP; - + const host = req.query.host?.toString(); + const org = req.query.org?.toString(); const gitRepository = await azureDevOpsApi.getRepoBuilds( projectName, repoName, top, + host, + org, ); res.status(200).json(gitRepository); @@ -99,7 +106,14 @@ export async function createRouter( router.get('/git-tags/:projectName/:repoName', async (req, res) => { const { projectName, repoName } = req.params; - const gitTags = await azureDevOpsApi.getGitTags(projectName, repoName); + const host = req.query.host?.toString(); + const org = req.query.org?.toString(); + const gitTags = await azureDevOpsApi.getGitTags( + projectName, + repoName, + host, + org, + ); res.status(200).json(gitTags); }); @@ -107,7 +121,8 @@ export async function createRouter( const { projectName, repoName } = req.params; const top = req.query.top ? Number(req.query.top) : DEFAULT_TOP; - + const host = req.query.host?.toString(); + const org = req.query.org?.toString(); const status = req.query.status ? Number(req.query.status) : PullRequestStatus.Active; @@ -121,6 +136,8 @@ export async function createRouter( projectName, repoName, pullRequestOptions, + host, + org, ); res.status(200).json(gitPullRequest); @@ -158,9 +175,13 @@ export async function createRouter( '/build-definitions/:projectName/:definitionName', async (req, res) => { const { projectName, definitionName } = req.params; + const host = req.query.host?.toString(); + const org = req.query.org?.toString(); const buildDefinitionList = await azureDevOpsApi.getBuildDefinitions( projectName, definitionName, + host, + org, ); res.status(200).json(buildDefinitionList); }, @@ -171,11 +192,15 @@ export async function createRouter( const repoName = req.query.repoName?.toString(); const definitionName = req.query.definitionName?.toString(); const top = req.query.top ? Number(req.query.top) : DEFAULT_TOP; + const host = req.query.host?.toString(); + const org = req.query.org?.toString(); const builds = await azureDevOpsApi.getBuildRuns( projectName, top, repoName, definitionName, + host, + org, ); res.status(200).json(builds); }); @@ -187,12 +212,14 @@ export async function createRouter( }); router.get('/readme/:projectName/:repoName', async (req, res) => { - const host = config.getString('azureDevOps.host'); - const organization = config.getString('azureDevOps.organization'); + const host = + req.query.host?.toString() ?? config.getString('azureDevOps.host'); + const org = + req.query.org?.toString() ?? config.getString('azureDevOps.organization'); const { projectName, repoName } = req.params; const readme = await azureDevOpsApi.getReadme( host, - organization, + org, projectName, repoName, ); diff --git a/plugins/azure-devops-common/api-report.md b/plugins/azure-devops-common/api-report.md index 262d5c8136..5bd1674fc8 100644 --- a/plugins/azure-devops-common/api-report.md +++ b/plugins/azure-devops-common/api-report.md @@ -223,6 +223,10 @@ export interface Readme { // @public (undocumented) export interface ReadmeConfig { + // (undocumented) + host?: string; + // (undocumented) + org?: string; // (undocumented) project: string; // (undocumented) diff --git a/plugins/azure-devops-common/src/types.ts b/plugins/azure-devops-common/src/types.ts index 380cb3e585..afb6083867 100644 --- a/plugins/azure-devops-common/src/types.ts +++ b/plugins/azure-devops-common/src/types.ts @@ -210,6 +210,8 @@ export interface Team { export interface ReadmeConfig { project: string; repo: string; + host?: string; + org?: string; } /** @public */ diff --git a/plugins/azure-devops/api-report.md b/plugins/azure-devops/api-report.md index 6b33762639..38c1eed279 100644 --- a/plugins/azure-devops/api-report.md +++ b/plugins/azure-devops/api-report.md @@ -71,6 +71,8 @@ export interface AzureDevOpsApi { projectName: string, repoName?: string, definitionName?: string, + host?: string, + org?: string, options?: BuildRunOptions, ): Promise<{ items: BuildRun[]; @@ -83,6 +85,8 @@ export interface AzureDevOpsApi { getGitTags( projectName: string, repoName: string, + host?: string, + org?: string, ): Promise<{ items: GitTag[]; }>; @@ -90,6 +94,8 @@ export interface AzureDevOpsApi { getPullRequests( projectName: string, repoName: string, + host?: string, + org?: string, options?: PullRequestOptions, ): Promise<{ items: PullRequest[]; @@ -100,6 +106,8 @@ export interface AzureDevOpsApi { getRepoBuilds( projectName: string, repoName: string, + host?: string, + org?: string, options?: RepoBuildOptions, ): Promise<{ items: RepoBuild[]; @@ -124,6 +132,8 @@ export class AzureDevOpsClient implements AzureDevOpsApi { projectName: string, repoName?: string, definitionName?: string, + host?: string, + org?: string, options?: BuildRunOptions, ): Promise<{ items: BuildRun[]; @@ -136,6 +146,8 @@ export class AzureDevOpsClient implements AzureDevOpsApi { getGitTags( projectName: string, repoName: string, + host?: string, + org?: string, ): Promise<{ items: GitTag[]; }>; @@ -143,6 +155,8 @@ export class AzureDevOpsClient implements AzureDevOpsApi { getPullRequests( projectName: string, repoName: string, + host?: string, + org?: string, options?: PullRequestOptions, ): Promise<{ items: PullRequest[]; @@ -153,6 +167,8 @@ export class AzureDevOpsClient implements AzureDevOpsApi { getRepoBuilds( projectName: string, repoName: string, + host?: string, + org?: string, options?: RepoBuildOptions, ): Promise<{ items: RepoBuild[]; diff --git a/plugins/azure-devops/src/api/AzureDevOpsApi.ts b/plugins/azure-devops/src/api/AzureDevOpsApi.ts index ce6a3cac39..89aa4b7d6e 100644 --- a/plugins/azure-devops/src/api/AzureDevOpsApi.ts +++ b/plugins/azure-devops/src/api/AzureDevOpsApi.ts @@ -40,17 +40,23 @@ export interface AzureDevOpsApi { getRepoBuilds( projectName: string, repoName: string, + host?: string, + org?: string, options?: RepoBuildOptions, ): Promise<{ items: RepoBuild[] }>; getGitTags( projectName: string, repoName: string, + host?: string, + org?: string, ): Promise<{ items: GitTag[] }>; getPullRequests( projectName: string, repoName: string, + host?: string, + org?: string, options?: PullRequestOptions, ): Promise<{ items: PullRequest[] }>; @@ -66,6 +72,8 @@ export interface AzureDevOpsApi { projectName: string, repoName?: string, definitionName?: string, + host?: string, + org?: string, options?: BuildRunOptions, ): Promise<{ items: BuildRun[] }>; diff --git a/plugins/azure-devops/src/api/AzureDevOpsClient.ts b/plugins/azure-devops/src/api/AzureDevOpsClient.ts index a202008798..76e38b064c 100644 --- a/plugins/azure-devops/src/api/AzureDevOpsClient.ts +++ b/plugins/azure-devops/src/api/AzureDevOpsClient.ts @@ -47,12 +47,20 @@ export class AzureDevOpsClient implements AzureDevOpsApi { public async getRepoBuilds( projectName: string, repoName: string, + host?: string, + org?: string, options?: RepoBuildOptions, ): Promise<{ items: RepoBuild[] }> { const queryString = new URLSearchParams(); if (options?.top) { queryString.append('top', options.top.toString()); } + if (host) { + queryString.append('host', host); + } + if (org) { + queryString.append('org', org); + } const urlSegment = `repo-builds/${encodeURIComponent( projectName, )}/${encodeURIComponent(repoName)}?${queryString}`; @@ -64,10 +72,19 @@ export class AzureDevOpsClient implements AzureDevOpsApi { public async getGitTags( projectName: string, repoName: string, + host?: string, + org?: string, ): Promise<{ items: GitTag[] }> { + const queryString = new URLSearchParams(); + if (host) { + queryString.append('host', host); + } + if (org) { + queryString.append('org', org); + } const urlSegment = `git-tags/${encodeURIComponent( projectName, - )}/${encodeURIComponent(repoName)}`; + )}/${encodeURIComponent(repoName)}?${queryString}`; const items = await this.get(urlSegment); return { items }; @@ -76,6 +93,8 @@ export class AzureDevOpsClient implements AzureDevOpsApi { public async getPullRequests( projectName: string, repoName: string, + host?: string, + org?: string, options?: PullRequestOptions, ): Promise<{ items: PullRequest[] }> { const queryString = new URLSearchParams(); @@ -85,6 +104,12 @@ export class AzureDevOpsClient implements AzureDevOpsApi { if (options?.status) { queryString.append('status', options.status.toString()); } + if (host) { + queryString.append('host', host); + } + if (org) { + queryString.append('org', org); + } const urlSegment = `pull-requests/${encodeURIComponent( projectName, )}/${encodeURIComponent(repoName)}?${queryString}`; @@ -113,12 +138,20 @@ export class AzureDevOpsClient implements AzureDevOpsApi { projectName: string, repoName?: string, definitionName?: string, + host?: string, + org?: string, options?: BuildRunOptions, ): Promise<{ items: BuildRun[] }> { const queryString = new URLSearchParams(); if (repoName) { queryString.append('repoName', repoName); } + if (host) { + queryString.append('host', host); + } + if (org) { + queryString.append('org', org); + } if (definitionName) { const definitionNames = definitionName.split(','); if (definitionNames.length > 1) { @@ -149,10 +182,17 @@ export class AzureDevOpsClient implements AzureDevOpsApi { } public async getReadme(opts: ReadmeConfig): Promise { + const queryString = new URLSearchParams(); + if (opts.host) { + queryString.append('host', opts.host); + } + if (opts.org) { + queryString.append('org', opts.org); + } return await this.get( `readme/${encodeURIComponent(opts.project)}/${encodeURIComponent( opts.repo, - )}`, + )}?${queryString}`, ); } diff --git a/plugins/azure-devops/src/hooks/useBuildRuns.ts b/plugins/azure-devops/src/hooks/useBuildRuns.ts index 0c10dc8db8..e335d2ffaf 100644 --- a/plugins/azure-devops/src/hooks/useBuildRuns.ts +++ b/plugins/azure-devops/src/hooks/useBuildRuns.ts @@ -42,8 +42,9 @@ export function useBuildRuns( const api = useApi(azureDevOpsApiRef); const { value, loading, error } = useAsync(() => { - const { project, repo, definition } = getAnnotationValuesFromEntity(entity); - return api.getBuildRuns(project, repo, definition, options); + const { project, repo, definition, host, org } = + getAnnotationValuesFromEntity(entity); + return api.getBuildRuns(project, repo, definition, host, org, options); }, [api]); return { diff --git a/plugins/azure-devops/src/hooks/useGitTags.ts b/plugins/azure-devops/src/hooks/useGitTags.ts index 8a2fb2825d..57489316da 100644 --- a/plugins/azure-devops/src/hooks/useGitTags.ts +++ b/plugins/azure-devops/src/hooks/useGitTags.ts @@ -30,8 +30,8 @@ export function useGitTags(entity: Entity): { const api = useApi(azureDevOpsApiRef); const { value, loading, error } = useAsync(() => { - const { project, repo } = getAnnotationValuesFromEntity(entity); - return api.getGitTags(project, repo as string); + const { project, repo, host, org } = getAnnotationValuesFromEntity(entity); + return api.getGitTags(project, repo as string, host, org); }, [api]); return { diff --git a/plugins/azure-devops/src/hooks/usePullRequests.ts b/plugins/azure-devops/src/hooks/usePullRequests.ts index 1ac6afae24..af2c4b1cc1 100644 --- a/plugins/azure-devops/src/hooks/usePullRequests.ts +++ b/plugins/azure-devops/src/hooks/usePullRequests.ts @@ -46,8 +46,8 @@ export function usePullRequests( const api = useApi(azureDevOpsApiRef); const { value, loading, error } = useAsync(() => { - const { project, repo } = getAnnotationValuesFromEntity(entity); - return api.getPullRequests(project, repo as string, options); + const { project, repo, host, org } = getAnnotationValuesFromEntity(entity); + return api.getPullRequests(project, repo as string, host, org, options); }, [api, top, status]); return { diff --git a/plugins/azure-devops/src/hooks/useReadme.ts b/plugins/azure-devops/src/hooks/useReadme.ts index 67d3c5dfd0..348b4219f0 100644 --- a/plugins/azure-devops/src/hooks/useReadme.ts +++ b/plugins/azure-devops/src/hooks/useReadme.ts @@ -30,8 +30,8 @@ export function useReadme(entity: Entity): { const api = useApi(azureDevOpsApiRef); const { value, loading, error } = useAsync(() => { - const { project, repo } = getAnnotationValuesFromEntity(entity); - return api.getReadme({ project, repo: repo as string }); + const { project, repo, host, org } = getAnnotationValuesFromEntity(entity); + return api.getReadme({ project, repo: repo as string, host, org }); }, [api]); return { From 2dc72e18170891e38214e2c8e084b69d0914d325 Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Fri, 1 Dec 2023 12:55:29 -0600 Subject: [PATCH 040/275] Fixed router tests Signed-off-by: Andre Wanlin --- .../src/service/router.test.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/plugins/azure-devops-backend/src/service/router.test.ts b/plugins/azure-devops-backend/src/service/router.test.ts index a77600feb0..65cb27271e 100644 --- a/plugins/azure-devops-backend/src/service/router.test.ts +++ b/plugins/azure-devops-backend/src/service/router.test.ts @@ -161,6 +161,8 @@ describe('createRouter', () => { 'myProject', 'af4ae3af-e747-4129-9bbc-d1329f6b0998', 40, + undefined, + undefined, ); expect(response.status).toEqual(200); expect(response.body).toEqual(builds); @@ -215,6 +217,8 @@ describe('createRouter', () => { 'myProject', 'myRepo', 50, + undefined, + undefined, ); expect(response.status).toEqual(200); expect(response.body).toEqual(repoBuilds); @@ -252,6 +256,8 @@ describe('createRouter', () => { expect(azureDevOpsApi.getGitTags).toHaveBeenCalledWith( 'myProject', 'myRepo', + undefined, + undefined, ); expect(response.status).toEqual(200); expect(response.body).toEqual(gitTags); @@ -315,6 +321,8 @@ describe('createRouter', () => { 'myProject', 'myRepo', { status: 1, top: 50 }, + undefined, + undefined, ); expect(response.status).toEqual(200); expect(response.body).toEqual(pullRequests); @@ -341,6 +349,8 @@ describe('createRouter', () => { expect(azureDevOpsApi.getBuildDefinitions).toHaveBeenCalledWith( 'myProject', 'myBuildDefinition', + undefined, + undefined, ); expect(response.status).toEqual(200); expect(response.body).toEqual(inputDefinitions); @@ -397,6 +407,8 @@ describe('createRouter', () => { 50, 'myRepo', undefined, + undefined, + undefined, ); expect(response.status).toEqual(200); expect(response.body).toEqual(buildRuns); @@ -452,6 +464,8 @@ describe('createRouter', () => { 50, undefined, 'myDefinition', + undefined, + undefined, ); expect(response.status).toEqual(200); expect(response.body).toEqual(buildRuns); From e131a1f5bfdbd3f96bb2cf594a69fac9cdd8f102 Mon Sep 17 00:00:00 2001 From: Deepankumar Loganathan Date: Fri, 1 Dec 2023 15:31:57 +0100 Subject: [PATCH 041/275] icon updated Signed-off-by: Deepankumar Loganathan --- microsite/data/plugins/azure-storage.yaml | 2 +- microsite/static/img/azure-storage-folder.png | Bin 0 -> 5907 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 microsite/static/img/azure-storage-folder.png diff --git a/microsite/data/plugins/azure-storage.yaml b/microsite/data/plugins/azure-storage.yaml index 47ab69735a..4d371a77d7 100644 --- a/microsite/data/plugins/azure-storage.yaml +++ b/microsite/data/plugins/azure-storage.yaml @@ -5,7 +5,7 @@ authorUrl: https://github.com/deepan10 category: Infrastructure description: Explore Azure Storage Blobs in Backstage. documentation: https://github.com/deepan10/backstage-plugins/tree/main/plugins/azure-storage -iconUrl: https://avatars.githubusercontent.com/u/6844498?s=200&v=4 +iconUrl: /img/azure-storage-folder.png npmPackageName: 'backstage-plugin-azure-storage' tags: - Azure diff --git a/microsite/static/img/azure-storage-folder.png b/microsite/static/img/azure-storage-folder.png new file mode 100644 index 0000000000000000000000000000000000000000..479340c5b3defe20b2ea09ddbd8214aed3dea451 GIT binary patch literal 5907 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 Date: Fri, 1 Dec 2023 13:55:31 -0600 Subject: [PATCH 042/275] Updated the READMEs Signed-off-by: Andre Wanlin --- plugins/azure-devops-backend/README.md | 41 +++++++++++++++++++- plugins/azure-devops/README.md | 52 +++++++++++++++++++++++--- 2 files changed, 87 insertions(+), 6 deletions(-) diff --git a/plugins/azure-devops-backend/README.md b/plugins/azure-devops-backend/README.md index 6810112bdb..2fe62c90eb 100644 --- a/plugins/azure-devops-backend/README.md +++ b/plugins/azure-devops-backend/README.md @@ -8,7 +8,7 @@ The following sections will help you get the Azure DevOps Backend plugin setup a ### Configuration -The Azure DevOps plugin requires the following YAML to be added to your app-config.yaml: +The Azure DevOps plugin requires the following YAML to be added to your `app-config.yaml`: ```yaml azureDevOps: @@ -23,6 +23,12 @@ Configuration Details: - `AZURE_TOKEN` environment variable must be set to a [Personal Access Token](https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=preview-page) with read access to both Code and Build - `organization` is your Azure DevOps Services (cloud) Organization name or for Azure DevOps Server (on-premise) this will be your Collection name +#### Multi Organization + +To support cases where you have multiple Azure DevOps organizations you will want to make sure to configure them in the `integrations.azure` section of your `app-config.yaml` as detailed in the [Azure DevOps Locations](https://backstage.io/docs/integrations/azure/locations) documentation. + +**Note:** You will still need to define the [configuration above](#configuration). + ### Up and Running Here's how to get the backend up and running: @@ -112,6 +118,39 @@ The Azure DevOps backend plugin includes the `AzureDevOpsAnnotatorProcessor` whi } ``` +To use this with the New Backend System you'll want to create a [backend module extension for the Catalog](https://backstage.io/docs/backend-system/building-backends/migrating#other-catalog-extensions) if you haven't already. Here's a basic example of this assuming you are only adding the `AzureDevOpsAnnotatorProcessor`, this would go in your `packages/backend/index.ts`: + +```diff + import { createBackend } from '@backstage/backend-defaults'; ++ import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; ++ import { coreServices, createBackendModule } from '@backstage/backend-plugin-api'; ++ import { AzureDevOpsAnnotatorProcessor } from '@backstage/plugin-azure-devops-backend'; + ++ const catalogModuleCustomExtensions = createBackendModule({ ++ pluginId: 'catalog', // name of the plugin that the module is targeting ++ moduleId: 'custom-extensions', ++ register(env) { ++ env.registerInit({ ++ deps: { ++ catalog: catalogProcessingExtensionPoint, ++ config: coreServices.rootConfig, ++ }, ++ async init({ catalog, config }) { ++ catalog.addProcessor(AzureDevOpsAnnotatorProcessor.fromConfig(config)); ++ }, ++ }); ++ }, ++ }); + + const backend = createBackend(); + + // ... other feature additions + ++ backend.add(catalogModuleCustomExtensions()); + + backend.start(); +``` + ## Links - [Frontend part of the plugin](https://github.com/backstage/backstage/tree/master/plugins/azure-devops) diff --git a/plugins/azure-devops/README.md b/plugins/azure-devops/README.md index 7eeae09813..25b88c6df6 100644 --- a/plugins/azure-devops/README.md +++ b/plugins/azure-devops/README.md @@ -72,6 +72,53 @@ dev.azure.com/build-definition: In this case `` will be the name of your Team Project and `` will be the name of the Build Definition you would like to see Builds for, and it's possible to add more Builds separated by a comma. If the Build Definition name has spaces in it make sure to put quotes around it. +#### Multiple Organizations + +If you you have multiple organizations you'll need to also add this annotation: + +```yaml +dev.azure.com/host-org: / +``` + +For this annotation `` will match the `host` value in the `integrations.azure` section in your `app-config.yaml` and `` will be the name of the Organization that is part of the `host`. Let's break this down with an example: + +Say we have the following `integrations.azure` section: + +```yaml +integrations: + azure: + - host: dev.azure.com + credentials: + - organizations: + - my-org + - my-other-org + clientId: ${AZURE_CLIENT_ID} + clientSecret: ${AZURE_CLIENT_SECRET} + tenantId: ${AZURE_TENANT_ID} + - organizations: + - another-org + clientId: ${AZURE_CLIENT_ID} + - host: server.company.com + credentials: + - organizations: + - yet-another-org + personalAccessToken: ${PERSONAL_ACCESS_TOKEN} +``` + +If the entity we are viewing lives in the `my-other-org` organization then the `dev.azure.com/host-org` annotation would look like this: + +```yaml +dev.azure.com/host-org: dev.azure.com/my-other-org +``` + +And if the entity was from `yet-another-org` it would look like this: + +```yaml +dev.azure.com/host-org: server.company.com/yet-another-org +``` + +**Note:** To save you time, effort, and confusion setting up these annotations manually you can use the `AzureDevOpsAnnotatorProcessor` processor which will add the `dev.azure.com/host-org` and `dev.azure.com/project-repo` annotations for you with the correct values. The Azure DevOps backend plugin has details on how to [add this processor](https://github.com/backstage/backstage/tree/master/plugins/azure-devops-backend#processor). + ### Azure Pipelines Component To get the Azure Pipelines component working you'll need to do the following two steps: @@ -247,8 +294,3 @@ To get the README component working you'll need to do the following two steps: - You'll need to add the `EntitySwitch.Case` above from step 2 to all the entity sections you want to see Readme in. For example if you wanted to see Readme when looking at Website entities then you would need to add this to the `websiteEntityPage` section. - The `if` prop is optional on the `EntitySwitch.Case`, you can remove it if you always want to see the tab even if the entity being viewed does not have the needed annotation - The `maxHeight` property on the `EntityAzureReadmeCard` will set the maximum screen size you would like to see, if not set it will default to 100% - -## Limitations - -- Currently multiple organizations are not supported -- Mixing Azure DevOps Services (cloud) and Azure DevOps Server (on-premise) is not supported From 45a2ede7315bf94b061b91126dc502272e04b5b3 Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Fri, 1 Dec 2023 13:58:27 -0600 Subject: [PATCH 043/275] Fixed typo Signed-off-by: Andre Wanlin --- plugins/azure-devops/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/azure-devops/README.md b/plugins/azure-devops/README.md index 25b88c6df6..d7335e54c8 100644 --- a/plugins/azure-devops/README.md +++ b/plugins/azure-devops/README.md @@ -74,7 +74,7 @@ In this case `` will be the name of your Team Project and `/ From bdd4aeb175ccd9f515b84dbe4b7d400044cb06e1 Mon Sep 17 00:00:00 2001 From: Philip Clark Date: Fri, 1 Dec 2023 15:13:54 -0500 Subject: [PATCH 044/275] docs: update okta provider doc Signed-off-by: Philip Clark --- docs/auth/okta/provider.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/auth/okta/provider.md b/docs/auth/okta/provider.md index 99ff664a67..2242e4a0f0 100644 --- a/docs/auth/okta/provider.md +++ b/docs/auth/okta/provider.md @@ -27,6 +27,8 @@ To add Okta authentication, you must create an Application from Okta: - `Controlled access`: (select as appropriate) - Click Save +The configuration examples provided above are suitable for local development. For a production deployment, substitute `http://localhost:7007` with the url that your Backstage instance is available at. + # Configuration The provider configuration can then be added to your `app-config.yaml` under the From bff06a38fd63540e574921831bc42233e78060c2 Mon Sep 17 00:00:00 2001 From: Aramis Sennyey Date: Fri, 1 Dec 2023 17:22:42 -0500 Subject: [PATCH 045/275] feat: add types to the generated exports Signed-off-by: Aramis Sennyey --- .../catalog-client/src/generated/index.ts | 1 + .../src/generated/models/index.ts | 52 +++++++++++++++++++ .../templates/typescript-backstage.yaml | 3 ++ .../typescript-backstage/index.mustache | 3 +- 4 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 packages/catalog-client/src/generated/models/index.ts diff --git a/packages/catalog-client/src/generated/index.ts b/packages/catalog-client/src/generated/index.ts index 7df0cfd292..0cf3e9cc49 100644 --- a/packages/catalog-client/src/generated/index.ts +++ b/packages/catalog-client/src/generated/index.ts @@ -15,3 +15,4 @@ */ export * from './apis'; +export * from './models'; diff --git a/packages/catalog-client/src/generated/models/index.ts b/packages/catalog-client/src/generated/models/index.ts new file mode 100644 index 0000000000..5a93dbb33a --- /dev/null +++ b/packages/catalog-client/src/generated/models/index.ts @@ -0,0 +1,52 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from '../models/AnalyzeLocationEntityField.model'; +export * from '../models/AnalyzeLocationExistingEntity.model'; +export * from '../models/AnalyzeLocationGenerateEntity.model'; +export * from '../models/AnalyzeLocationRequest.model'; +export * from '../models/AnalyzeLocationResponse.model'; +export * from '../models/CreateLocation201Response.model'; +export * from '../models/CreateLocationRequest.model'; +export * from '../models/EntitiesBatchResponse.model'; +export * from '../models/EntitiesQueryResponse.model'; +export * from '../models/EntitiesQueryResponsePageInfo.model'; +export * from '../models/Entity.model'; +export * from '../models/EntityAncestryResponse.model'; +export * from '../models/EntityAncestryResponseItemsInner.model'; +export * from '../models/EntityFacet.model'; +export * from '../models/EntityFacetsResponse.model'; +export * from '../models/EntityLink.model'; +export * from '../models/EntityMeta.model'; +export * from '../models/EntityRelation.model'; +export * from '../models/ErrorError.model'; +export * from '../models/ErrorRequest.model'; +export * from '../models/ErrorResponse.model'; +export * from '../models/GetEntitiesByRefsRequest.model'; +export * from '../models/GetLocations200ResponseInner.model'; +export * from '../models/Location.model'; +export * from '../models/LocationInput.model'; +export * from '../models/LocationSpec.model'; +export * from '../models/ModelError.model'; +export * from '../models/NullableEntity.model'; +export * from '../models/RecursivePartialEntity.model'; +export * from '../models/RecursivePartialEntityMeta.model'; +export * from '../models/RecursivePartialEntityMetaAllOf.model'; +export * from '../models/RecursivePartialEntityRelation.model'; +export * from '../models/RefreshEntityRequest.model'; +export * from '../models/ValidateEntity400Response.model'; +export * from '../models/ValidateEntity400ResponseErrorsInner.model'; +export * from '../models/ValidateEntityRequest.model'; diff --git a/packages/repo-tools/templates/typescript-backstage.yaml b/packages/repo-tools/templates/typescript-backstage.yaml index eaa72d7179..7137b5a8c6 100644 --- a/packages/repo-tools/templates/typescript-backstage.yaml +++ b/packages/repo-tools/templates/typescript-backstage.yaml @@ -8,6 +8,9 @@ files: model.mustache: templateType: Model destinationFilename: .model.ts + models/models_all.mustache: + templateType: SupportingFiles + destinationFilename: models/index.ts types/fetch.ts: {} types/discovery.ts: {} apis/index.mustache: diff --git a/packages/repo-tools/templates/typescript-backstage/index.mustache b/packages/repo-tools/templates/typescript-backstage/index.mustache index 8436cce60b..b95e48ff08 100644 --- a/packages/repo-tools/templates/typescript-backstage/index.mustache +++ b/packages/repo-tools/templates/typescript-backstage/index.mustache @@ -1,3 +1,4 @@ // -export * from './apis' +export * from './apis'; +export * from './models'; \ No newline at end of file From da3c4dbf5d10b1fca6c27d056afeab1e533a3f3e Mon Sep 17 00:00:00 2001 From: Aramis Sennyey Date: Fri, 1 Dec 2023 17:25:32 -0500 Subject: [PATCH 046/275] add changeset Signed-off-by: Aramis Sennyey --- .changeset/gentle-timers-fail.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/gentle-timers-fail.md diff --git a/.changeset/gentle-timers-fail.md b/.changeset/gentle-timers-fail.md new file mode 100644 index 0000000000..3ac6e207a8 --- /dev/null +++ b/.changeset/gentle-timers-fail.md @@ -0,0 +1,5 @@ +--- +'@backstage/repo-tools': patch +--- + +Updates the `schema openapi generate-client` command to export all generated types from the generated directory. From dde40de392ab598898c836048dbaacafa3d73fde Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Fri, 1 Dec 2023 13:50:01 +0100 Subject: [PATCH 047/275] refactor: apply review suggestions Signed-off-by: Camila Belo --- .changeset/brave-beers-happen.md | 2 +- .changeset/good-wolves-leave.md | 2 +- .changeset/sharp-dingos-learn.md | 2 +- .../examples/notFoundErrorPageExtension.tsx | 4 +-- .../src/extensions/CoreRoutes.tsx | 10 +++--- .../src/extensions/components.tsx | 13 +++----- .../src/wiring/createApp.test.tsx | 7 ++-- .../frontend-app-api/src/wiring/createApp.tsx | 2 -- packages/frontend-plugin-api/api-report.md | 33 ++++++++----------- .../src/apis/definitions/ComponentsApi.ts | 13 +++++++- .../src/components/ComponentRef.tsx | 9 +---- .../src/components/ExtensionBoundary.tsx | 17 +++------- .../src/components/index.ts | 2 +- packages/frontend-plugin-api/src/index.ts | 1 - packages/frontend-plugin-api/src/types.ts | 18 ++++------ .../src/wiring/coreExtensionData.ts | 2 +- yarn.lock | 6 ++-- 17 files changed, 60 insertions(+), 83 deletions(-) diff --git a/.changeset/brave-beers-happen.md b/.changeset/brave-beers-happen.md index 8a16ed4824..34bbb95666 100644 --- a/.changeset/brave-beers-happen.md +++ b/.changeset/brave-beers-happen.md @@ -2,4 +2,4 @@ '@backstage/frontend-plugin-api': patch --- -**_BREAKING_**: update alpha component ref type to be more specific than any and use new plugin type for error boundary component extensions. +Update alpha component ref type to be more specific than any, delete boot page component and use new plugin type for error boundary component extensions. diff --git a/.changeset/good-wolves-leave.md b/.changeset/good-wolves-leave.md index c2cde8bfed..51ac99a55a 100644 --- a/.changeset/good-wolves-leave.md +++ b/.changeset/good-wolves-leave.md @@ -2,4 +2,4 @@ '@backstage/frontend-app-api': patch --- -**_BREAKING_**: Use the new plugin type for error boundary components. +Use the new plugin type for error boundary components. diff --git a/.changeset/sharp-dingos-learn.md b/.changeset/sharp-dingos-learn.md index 9dbb7ed8f4..9447ca9698 100644 --- a/.changeset/sharp-dingos-learn.md +++ b/.changeset/sharp-dingos-learn.md @@ -2,4 +2,4 @@ '@backstage/core-compat-api': patch --- -**_BREAKING_**: delete alpha DI compatibility helper for components, migrating components should be simple without an helper. +Delete alpha DI compatibility helper for components, migrating components should be simple without a helper. diff --git a/packages/app-next/src/examples/notFoundErrorPageExtension.tsx b/packages/app-next/src/examples/notFoundErrorPageExtension.tsx index 6cdaff978f..06e9b50bb8 100644 --- a/packages/app-next/src/examples/notFoundErrorPageExtension.tsx +++ b/packages/app-next/src/examples/notFoundErrorPageExtension.tsx @@ -17,7 +17,7 @@ import React from 'react'; import { createComponentExtension, - coreComponentsRefs, + coreComponentRefs, } from '@backstage/frontend-plugin-api'; import { Box, Typography } from '@material-ui/core'; import { Button } from '@backstage/core-components'; @@ -51,6 +51,6 @@ export function CustomNotFoundErrorPage() { } export default createComponentExtension({ - ref: coreComponentsRefs.notFoundErrorPage, + ref: coreComponentRefs.notFoundErrorPage, component: { sync: () => CustomNotFoundErrorPage }, }); diff --git a/packages/frontend-app-api/src/extensions/CoreRoutes.tsx b/packages/frontend-app-api/src/extensions/CoreRoutes.tsx index 1b79231699..155a5b60fa 100644 --- a/packages/frontend-app-api/src/extensions/CoreRoutes.tsx +++ b/packages/frontend-app-api/src/extensions/CoreRoutes.tsx @@ -19,9 +19,8 @@ import { createExtension, coreExtensionData, createExtensionInput, - coreComponentsRefs, - useApi, - componentsApiRef, + coreComponentRefs, + useComponentRef, } from '@backstage/frontend-plugin-api'; import { useRoutes } from 'react-router-dom'; @@ -41,9 +40,8 @@ export const CoreRoutes = createExtension({ }, factory({ inputs }) { const Routes = () => { - const componentsApi = useApi(componentsApiRef); - const NotFoundErrorPage = componentsApi.getComponent( - coreComponentsRefs.notFoundErrorPage, + const NotFoundErrorPage = useComponentRef( + coreComponentRefs.notFoundErrorPage, ); const element = useRoutes([ diff --git a/packages/frontend-app-api/src/extensions/components.tsx b/packages/frontend-app-api/src/extensions/components.tsx index e13c1b2f3b..44d479f170 100644 --- a/packages/frontend-app-api/src/extensions/components.tsx +++ b/packages/frontend-app-api/src/extensions/components.tsx @@ -20,7 +20,7 @@ import { Button } from '@material-ui/core'; import { createComponentExtension, - coreComponentsRefs, + coreComponentRefs, } from '@backstage/frontend-plugin-api'; import { ErrorPanel } from '@backstage/core-components'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports @@ -28,22 +28,17 @@ import { components as defaultComponents } from '../../../app-defaults/src/defau // eslint-disable-next-line @backstage/no-relative-monorepo-imports export const DefaultProgressComponent = createComponentExtension({ - ref: coreComponentsRefs.progress, + ref: coreComponentRefs.progress, component: { sync: () => defaultComponents.Progress }, }); -export const DefaultBootErrorPageComponent = createComponentExtension({ - ref: coreComponentsRefs.bootErrorPage, - component: { sync: () => defaultComponents.BootErrorPage }, -}); - export const DefaultNotFoundErrorPageComponent = createComponentExtension({ - ref: coreComponentsRefs.notFoundErrorPage, + ref: coreComponentRefs.notFoundErrorPage, component: { sync: () => defaultComponents.NotFoundErrorPage }, }); export const DefaultErrorBoundaryComponent = createComponentExtension({ - ref: coreComponentsRefs.errorBoundaryFallback, + ref: coreComponentRefs.errorBoundaryFallback, component: { sync: () => props => { const { plugin, error, resetError } = props; diff --git a/packages/frontend-app-api/src/wiring/createApp.test.tsx b/packages/frontend-app-api/src/wiring/createApp.test.tsx index 2713a9743e..32773de7e1 100644 --- a/packages/frontend-app-api/src/wiring/createApp.test.tsx +++ b/packages/frontend-app-api/src/wiring/createApp.test.tsx @@ -201,10 +201,9 @@ describe('createApp', () => { ] components [ - - - - + + + ] themes [ diff --git a/packages/frontend-app-api/src/wiring/createApp.tsx b/packages/frontend-app-api/src/wiring/createApp.tsx index f58dfb3159..dcfbd1faf2 100644 --- a/packages/frontend-app-api/src/wiring/createApp.tsx +++ b/packages/frontend-app-api/src/wiring/createApp.tsx @@ -96,7 +96,6 @@ import { createAppTree } from '../tree'; import { DefaultProgressComponent, DefaultErrorBoundaryComponent, - DefaultBootErrorPageComponent, DefaultNotFoundErrorPageComponent, } from '../extensions/components'; import { AppNode } from '@backstage/frontend-plugin-api'; @@ -117,7 +116,6 @@ export const builtinExtensions = [ CoreLayout, DefaultProgressComponent, DefaultErrorBoundaryComponent, - DefaultBootErrorPageComponent, DefaultNotFoundErrorPageComponent, LightTheme, DarkTheme, diff --git a/packages/frontend-plugin-api/api-report.md b/packages/frontend-plugin-api/api-report.md index 7342558560..38f6583519 100644 --- a/packages/frontend-plugin-api/api-report.md +++ b/packages/frontend-plugin-api/api-report.md @@ -64,7 +64,6 @@ import { OpenIdConnectApi } from '@backstage/core-plugin-api'; import { PendingOAuthRequest } from '@backstage/core-plugin-api'; import { ProfileInfo } from '@backstage/core-plugin-api'; import { ProfileInfoApi } from '@backstage/core-plugin-api'; -import { PropsWithChildren } from 'react'; import { default as React_2 } from 'react'; import { ReactNode } from 'react'; import { SessionApi } from '@backstage/core-plugin-api'; @@ -321,29 +320,18 @@ export interface ConfigurableExtensionDataRef< } // @public (undocumented) -export type CoreBootErrorPageProps = PropsWithChildren<{ - step: 'load-config' | 'load-chunk'; - error: Error; -}>; - -// @public (undocumented) -export const coreComponentsRefs: { - progress: ComponentRef<{ - children?: ReactNode; - }>; - bootErrorPage: ComponentRef; - notFoundErrorPage: ComponentRef<{ - children?: ReactNode; - }>; +export const coreComponentRefs: { + progress: ComponentRef; + notFoundErrorPage: ComponentRef; errorBoundaryFallback: ComponentRef; }; // @public (undocumented) -export type CoreErrorBoundaryFallbackProps = PropsWithChildren<{ +export type CoreErrorBoundaryFallbackProps = { plugin?: BackstagePlugin; error: Error; resetError: () => void; -}>; +}; // @public (undocumented) export const coreExtensionData: { @@ -364,10 +352,12 @@ export const coreExtensionData: { }; // @public (undocumented) -export type CoreNotFoundErrorPageProps = PropsWithChildren<{}>; +export type CoreNotFoundErrorPageProps = { + children?: ReactNode; +}; // @public (undocumented) -export type CoreProgressProps = PropsWithChildren<{}>; +export type CoreProgressProps = {}; // @public (undocumented) export function createApiExtension< @@ -952,6 +942,11 @@ export { useApi }; export { useApiHolder }; +// @public +export function useComponentRef( + ref: ComponentRef, +): ComponentType; + // @public export function useRouteRef< TOptional extends boolean, diff --git a/packages/frontend-plugin-api/src/apis/definitions/ComponentsApi.ts b/packages/frontend-plugin-api/src/apis/definitions/ComponentsApi.ts index dee17e7d97..c5e9d2c44f 100644 --- a/packages/frontend-plugin-api/src/apis/definitions/ComponentsApi.ts +++ b/packages/frontend-plugin-api/src/apis/definitions/ComponentsApi.ts @@ -15,7 +15,7 @@ */ import { ComponentType } from 'react'; -import { createApiRef } from '@backstage/core-plugin-api'; +import { createApiRef, useApi } from '@backstage/core-plugin-api'; import { ComponentRef } from '../../components'; /** @@ -36,3 +36,14 @@ export interface ComponentsApi { export const componentsApiRef = createApiRef({ id: 'core.components', }); + +/** + * @public + * Returns the component associated with the given ref. + */ +export function useComponentRef( + ref: ComponentRef, +): ComponentType { + const componentsApi = useApi(componentsApiRef); + return componentsApi.getComponent(ref); +} diff --git a/packages/frontend-plugin-api/src/components/ComponentRef.tsx b/packages/frontend-plugin-api/src/components/ComponentRef.tsx index dd2e65a61f..50df9552ec 100644 --- a/packages/frontend-plugin-api/src/components/ComponentRef.tsx +++ b/packages/frontend-plugin-api/src/components/ComponentRef.tsx @@ -15,7 +15,6 @@ */ import { - CoreBootErrorPageProps, CoreErrorBoundaryFallbackProps, CoreNotFoundErrorPageProps, CoreProgressProps, @@ -41,11 +40,6 @@ const coreProgressComponentRef = createComponentRef({ id: 'core.components.progress', }); -const coreBootErrorPageComponentRef = - createComponentRef({ - id: 'core.components.bootErrorPage', - }); - const coreNotFoundErrorPageComponentRef = createComponentRef({ id: 'core.components.notFoundErrorPage', @@ -57,9 +51,8 @@ const coreErrorBoundaryFallbackComponentRef = }); /** @public */ -export const coreComponentsRefs = { +export const coreComponentRefs = { progress: coreProgressComponentRef, - bootErrorPage: coreBootErrorPageComponentRef, notFoundErrorPage: coreNotFoundErrorPageComponentRef, errorBoundaryFallback: coreErrorBoundaryFallbackComponentRef, }; diff --git a/packages/frontend-plugin-api/src/components/ExtensionBoundary.tsx b/packages/frontend-plugin-api/src/components/ExtensionBoundary.tsx index d830f665f0..db5c911cef 100644 --- a/packages/frontend-plugin-api/src/components/ExtensionBoundary.tsx +++ b/packages/frontend-plugin-api/src/components/ExtensionBoundary.tsx @@ -20,16 +20,12 @@ import React, { Suspense, useEffect, } from 'react'; -import { - AnalyticsContext, - useAnalytics, - useApi, -} from '@backstage/core-plugin-api'; +import { AnalyticsContext, useAnalytics } from '@backstage/core-plugin-api'; import { ErrorBoundary } from './ErrorBoundary'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports import { routableExtensionRenderedEvent } from '../../../core-plugin-api/src/analytics/Tracker'; -import { AppNode, componentsApiRef } from '../apis'; -import { coreComponentsRefs } from './ComponentRef'; +import { AppNode, useComponentRef } from '../apis'; +import { coreComponentRefs } from './ComponentRef'; type RouteTrackerProps = PropsWithChildren<{ disableTracking?: boolean; @@ -61,13 +57,10 @@ export interface ExtensionBoundaryProps { /** @public */ export function ExtensionBoundary(props: ExtensionBoundaryProps) { const { node, routable, children } = props; - const componentsApi = useApi(componentsApiRef); const plugin = node.spec.source; - const Progress = componentsApi.getComponent(coreComponentsRefs.progress); - const fallback = componentsApi.getComponent( - coreComponentsRefs.errorBoundaryFallback, - ); + const Progress = useComponentRef(coreComponentRefs.progress); + const fallback = useComponentRef(coreComponentRefs.errorBoundaryFallback); // Skipping "routeRef" attribute in the new system, the extension "id" should provide more insight const attributes = { diff --git a/packages/frontend-plugin-api/src/components/index.ts b/packages/frontend-plugin-api/src/components/index.ts index a7d947599f..893918059b 100644 --- a/packages/frontend-plugin-api/src/components/index.ts +++ b/packages/frontend-plugin-api/src/components/index.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -export { coreComponentsRefs, type ComponentRef } from './ComponentRef'; +export { coreComponentRefs, type ComponentRef } from './ComponentRef'; export { ExtensionBoundary, diff --git a/packages/frontend-plugin-api/src/index.ts b/packages/frontend-plugin-api/src/index.ts index 04cbddd336..72ebe34795 100644 --- a/packages/frontend-plugin-api/src/index.ts +++ b/packages/frontend-plugin-api/src/index.ts @@ -32,7 +32,6 @@ export * from './wiring'; export type { CoreProgressProps, - CoreBootErrorPageProps, CoreNotFoundErrorPageProps, CoreErrorBoundaryFallbackProps, } from './types'; diff --git a/packages/frontend-plugin-api/src/types.ts b/packages/frontend-plugin-api/src/types.ts index a69c483b5c..4d0fb1ac4b 100644 --- a/packages/frontend-plugin-api/src/types.ts +++ b/packages/frontend-plugin-api/src/types.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { PropsWithChildren } from 'react'; +import { ReactNode } from 'react'; import { BackstagePlugin } from './wiring'; // TODO(Rugvip): This might be a quite useful utility type, maybe add to @backstage/types? @@ -25,20 +25,16 @@ import { BackstagePlugin } from './wiring'; export type Expand = T extends infer O ? { [K in keyof O]: O[K] } : never; /** @public */ -export type CoreProgressProps = PropsWithChildren<{}>; +export type CoreProgressProps = {}; /** @public */ -export type CoreBootErrorPageProps = PropsWithChildren<{ - step: 'load-config' | 'load-chunk'; - error: Error; -}>; +export type CoreNotFoundErrorPageProps = { + children?: ReactNode; +}; /** @public */ -export type CoreNotFoundErrorPageProps = PropsWithChildren<{}>; - -/** @public */ -export type CoreErrorBoundaryFallbackProps = PropsWithChildren<{ +export type CoreErrorBoundaryFallbackProps = { plugin?: BackstagePlugin; error: Error; resetError: () => void; -}>; +}; diff --git a/packages/frontend-plugin-api/src/wiring/coreExtensionData.ts b/packages/frontend-plugin-api/src/wiring/coreExtensionData.ts index 47a77414a0..d52a672679 100644 --- a/packages/frontend-plugin-api/src/wiring/coreExtensionData.ts +++ b/packages/frontend-plugin-api/src/wiring/coreExtensionData.ts @@ -49,5 +49,5 @@ export const coreExtensionData = { component: createExtensionDataRef<{ ref: ComponentRef; impl: ComponentType; - }>('component.ref'), + }>('core.component'), }; diff --git a/yarn.lock b/yarn.lock index 0d8d076b45..9759cf8787 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3916,7 +3916,7 @@ __metadata: languageName: node linkType: hard -"@backstage/core-components@npm:^0.13.7, @backstage/core-components@npm:^0.13.8": +"@backstage/core-components@npm:^0.13.8": version: 0.13.8 resolution: "@backstage/core-components@npm:0.13.8" dependencies: @@ -4042,7 +4042,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/core-plugin-api@npm:^1.3.0, @backstage/core-plugin-api@npm:^1.5.0, @backstage/core-plugin-api@npm:^1.7.0, @backstage/core-plugin-api@npm:^1.8.0": +"@backstage/core-plugin-api@npm:^1.3.0, @backstage/core-plugin-api@npm:^1.5.0, @backstage/core-plugin-api@npm:^1.8.0": version: 1.8.0 resolution: "@backstage/core-plugin-api@npm:1.8.0" dependencies: @@ -5950,7 +5950,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-catalog-react@npm:^1.2.4, @backstage/plugin-catalog-react@npm:^1.8.5, @backstage/plugin-catalog-react@npm:^1.9.1": +"@backstage/plugin-catalog-react@npm:^1.2.4, @backstage/plugin-catalog-react@npm:^1.9.1": version: 1.9.1 resolution: "@backstage/plugin-catalog-react@npm:1.9.1" dependencies: From 5adfd1447f738ed338da673aa10b4c2cdce2c0c5 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Fri, 1 Dec 2023 12:07:53 +0100 Subject: [PATCH 048/275] feat(frontend-test-utils): start migrating renderInTestApp Signed-off-by: Camila Belo --- packages/frontend-test-utils/api-report.md | 5 +++ packages/frontend-test-utils/src/app/index.ts | 2 + .../src/app/renderInTestApp.test.tsx | 27 +++++++++++++ .../src/app/renderInTestApp.tsx | 38 +++++++++++++++++++ yarn.lock | 6 +-- 5 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 packages/frontend-test-utils/src/app/renderInTestApp.test.tsx create mode 100644 packages/frontend-test-utils/src/app/renderInTestApp.tsx diff --git a/packages/frontend-test-utils/api-report.md b/packages/frontend-test-utils/api-report.md index 14e1c68c4c..36fc5e30b6 100644 --- a/packages/frontend-test-utils/api-report.md +++ b/packages/frontend-test-utils/api-report.md @@ -3,6 +3,8 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +/// + import { ErrorWithContext } from '@backstage/test-utils'; import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; import { JsonObject } from '@backstage/types'; @@ -63,6 +65,9 @@ export { MockStorageApi }; export { MockStorageBucket }; +// @public +export function renderInTestApp(element: JSX.Element): RenderResult; + export { setupRequestMockHandlers }; export { TestApiProvider }; diff --git a/packages/frontend-test-utils/src/app/index.ts b/packages/frontend-test-utils/src/app/index.ts index 3152fac6e7..3f19146c5c 100644 --- a/packages/frontend-test-utils/src/app/index.ts +++ b/packages/frontend-test-utils/src/app/index.ts @@ -18,3 +18,5 @@ export { createExtensionTester, type ExtensionTester, } from './createExtensionTester'; + +export { renderInTestApp } from './renderInTestApp'; diff --git a/packages/frontend-test-utils/src/app/renderInTestApp.test.tsx b/packages/frontend-test-utils/src/app/renderInTestApp.test.tsx new file mode 100644 index 0000000000..e13d1157ef --- /dev/null +++ b/packages/frontend-test-utils/src/app/renderInTestApp.test.tsx @@ -0,0 +1,27 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { screen } from '@testing-library/react'; +import { renderInTestApp } from './renderInTestApp'; + +describe('renderInTestApp', () => { + it('should render the given component in a page', async () => { + const Component = () =>
Test
; + renderInTestApp(); + expect(screen.getByText('Test')).toBeInTheDocument(); + }); +}); diff --git a/packages/frontend-test-utils/src/app/renderInTestApp.tsx b/packages/frontend-test-utils/src/app/renderInTestApp.tsx new file mode 100644 index 0000000000..f4011535a4 --- /dev/null +++ b/packages/frontend-test-utils/src/app/renderInTestApp.tsx @@ -0,0 +1,38 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + coreExtensionData, + createExtension, +} from '@backstage/frontend-plugin-api'; +import { createExtensionTester } from './createExtensionTester'; + +/** + * @public + * Renders the given element in a test app, for use in unit tests. + */ +export function renderInTestApp(element: JSX.Element) { + const extension = createExtension({ + namespace: 'test', + attachTo: { id: 'core', input: 'root' }, + output: { + element: coreExtensionData.reactElement, + }, + factory: () => ({ element }), + }); + const tester = createExtensionTester(extension); + return tester.render(); +} diff --git a/yarn.lock b/yarn.lock index 0d8d076b45..9759cf8787 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3916,7 +3916,7 @@ __metadata: languageName: node linkType: hard -"@backstage/core-components@npm:^0.13.7, @backstage/core-components@npm:^0.13.8": +"@backstage/core-components@npm:^0.13.8": version: 0.13.8 resolution: "@backstage/core-components@npm:0.13.8" dependencies: @@ -4042,7 +4042,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/core-plugin-api@npm:^1.3.0, @backstage/core-plugin-api@npm:^1.5.0, @backstage/core-plugin-api@npm:^1.7.0, @backstage/core-plugin-api@npm:^1.8.0": +"@backstage/core-plugin-api@npm:^1.3.0, @backstage/core-plugin-api@npm:^1.5.0, @backstage/core-plugin-api@npm:^1.8.0": version: 1.8.0 resolution: "@backstage/core-plugin-api@npm:1.8.0" dependencies: @@ -5950,7 +5950,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-catalog-react@npm:^1.2.4, @backstage/plugin-catalog-react@npm:^1.8.5, @backstage/plugin-catalog-react@npm:^1.9.1": +"@backstage/plugin-catalog-react@npm:^1.2.4, @backstage/plugin-catalog-react@npm:^1.9.1": version: 1.9.1 resolution: "@backstage/plugin-catalog-react@npm:1.9.1" dependencies: From b9aa6e45a1bf8614af76e5d4f24efcc95eb42eb9 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Sat, 2 Dec 2023 12:27:24 +0100 Subject: [PATCH 049/275] docs: add changeset filte Signed-off-by: Camila Belo --- .changeset/forty-mirrors-carry.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/forty-mirrors-carry.md diff --git a/.changeset/forty-mirrors-carry.md b/.changeset/forty-mirrors-carry.md new file mode 100644 index 0000000000..d31d635329 --- /dev/null +++ b/.changeset/forty-mirrors-carry.md @@ -0,0 +1,5 @@ +--- +'@backstage/frontend-test-utils': patch +--- + +Migrate `renderInTestApp` to `@backstage/frontend-test-utils` for testing individual React components in an app. From c8e253a2e8dd8a4a99314e8902fe3dce72f0f84b Mon Sep 17 00:00:00 2001 From: Andre Wanlin <67169551+awanlin@users.noreply.github.com> Date: Sat, 2 Dec 2023 06:12:01 -0600 Subject: [PATCH 050/275] Update docs/features/techdocs/how-to-guides.md Signed-off-by: Andre Wanlin <67169551+awanlin@users.noreply.github.com> --- docs/features/techdocs/how-to-guides.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/techdocs/how-to-guides.md b/docs/features/techdocs/how-to-guides.md index 4a562dd1c0..afc257f20b 100644 --- a/docs/features/techdocs/how-to-guides.md +++ b/docs/features/techdocs/how-to-guides.md @@ -508,7 +508,7 @@ Done! You now have support for TechDocs in your own software template! If your Backstage instance does not have internet access, the generation will fail. TechDocs tries to download the Roboto font from Google. You can disable it by adding the following lines to mkdocs.yaml: -```markdown +```yaml theme: name: material font: false From 64301d3d808a8f847911558b79611c52f5fd17d8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 2 Dec 2023 12:11:39 +0000 Subject: [PATCH 051/275] fix(deps): update rjsf monorepo to v5.15.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .changeset/renovate-ccaf2c8.md | 11 +++++ plugins/home-react/package.json | 2 +- plugins/home/package.json | 8 ++-- plugins/scaffolder-react/package.json | 8 ++-- plugins/scaffolder/package.json | 8 ++-- yarn.lock | 58 +++++++++++++-------------- 6 files changed, 53 insertions(+), 42 deletions(-) create mode 100644 .changeset/renovate-ccaf2c8.md diff --git a/.changeset/renovate-ccaf2c8.md b/.changeset/renovate-ccaf2c8.md new file mode 100644 index 0000000000..ac4c2fa16e --- /dev/null +++ b/.changeset/renovate-ccaf2c8.md @@ -0,0 +1,11 @@ +--- +'@backstage/plugin-home-react': patch +'@backstage/plugin-home': patch +'@backstage/plugin-scaffolder-react': patch +'@backstage/plugin-scaffolder': patch +--- + +Updated dependency `@rjsf/utils` to `5.15.0`. +Updated dependency `@rjsf/core` to `5.15.0`. +Updated dependency `@rjsf/material-ui` to `5.15.0`. +Updated dependency `@rjsf/validator-ajv8` to `5.15.0`. diff --git a/plugins/home-react/package.json b/plugins/home-react/package.json index 60dc92c3e7..28a059b5ec 100644 --- a/plugins/home-react/package.json +++ b/plugins/home-react/package.json @@ -38,7 +38,7 @@ "@backstage/core-plugin-api": "workspace:^", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", - "@rjsf/utils": "5.14.3", + "@rjsf/utils": "5.15.0", "@types/react": "^16.13.1 || ^17.0.0" }, "peerDependencies": { diff --git a/plugins/home/package.json b/plugins/home/package.json index 57a5189fc9..913303dfe6 100644 --- a/plugins/home/package.json +++ b/plugins/home/package.json @@ -61,10 +61,10 @@ "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.61", - "@rjsf/core": "5.14.3", - "@rjsf/material-ui": "5.14.3", - "@rjsf/utils": "5.14.3", - "@rjsf/validator-ajv8": "5.14.3", + "@rjsf/core": "5.15.0", + "@rjsf/material-ui": "5.15.0", + "@rjsf/utils": "5.15.0", + "@rjsf/validator-ajv8": "5.15.0", "@types/react": "^16.13.1 || ^17.0.0", "lodash": "^4.17.21", "luxon": "^3.4.3", diff --git a/plugins/scaffolder-react/package.json b/plugins/scaffolder-react/package.json index 9849696d19..19820013ca 100644 --- a/plugins/scaffolder-react/package.json +++ b/plugins/scaffolder-react/package.json @@ -60,10 +60,10 @@ "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.61", "@react-hookz/web": "^23.0.0", - "@rjsf/core": "5.14.3", - "@rjsf/material-ui": "5.14.3", - "@rjsf/utils": "5.14.3", - "@rjsf/validator-ajv8": "5.14.3", + "@rjsf/core": "5.15.0", + "@rjsf/material-ui": "5.15.0", + "@rjsf/utils": "5.15.0", + "@rjsf/validator-ajv8": "5.15.0", "@types/json-schema": "^7.0.9", "@types/react": "^16.13.1 || ^17.0.0", "classnames": "^2.2.6", diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index 13257e2731..ddfd978590 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -68,10 +68,10 @@ "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.61", "@react-hookz/web": "^23.0.0", - "@rjsf/core": "5.14.3", - "@rjsf/material-ui": "5.14.3", - "@rjsf/utils": "5.14.3", - "@rjsf/validator-ajv8": "5.14.3", + "@rjsf/core": "5.15.0", + "@rjsf/material-ui": "5.15.0", + "@rjsf/utils": "5.15.0", + "@rjsf/validator-ajv8": "5.15.0", "@types/react": "^16.13.1 || ^17.0.0", "@uiw/react-codemirror": "^4.9.3", "classnames": "^2.2.6", diff --git a/yarn.lock b/yarn.lock index 486d42f8d3..41340ede8c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7355,7 +7355,7 @@ __metadata: "@backstage/test-utils": "workspace:^" "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 - "@rjsf/utils": 5.14.3 + "@rjsf/utils": 5.15.0 "@testing-library/dom": ^9.0.0 "@testing-library/jest-dom": ^6.0.0 "@testing-library/react": ^14.0.0 @@ -7392,10 +7392,10 @@ __metadata: "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 - "@rjsf/core": 5.14.3 - "@rjsf/material-ui": 5.14.3 - "@rjsf/utils": 5.14.3 - "@rjsf/validator-ajv8": 5.14.3 + "@rjsf/core": 5.15.0 + "@rjsf/material-ui": 5.15.0 + "@rjsf/utils": 5.15.0 + "@rjsf/validator-ajv8": 5.15.0 "@testing-library/dom": ^9.0.0 "@testing-library/jest-dom": ^6.0.0 "@testing-library/react": ^14.0.0 @@ -8852,10 +8852,10 @@ __metadata: "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 "@react-hookz/web": ^23.0.0 - "@rjsf/core": 5.14.3 - "@rjsf/material-ui": 5.14.3 - "@rjsf/utils": 5.14.3 - "@rjsf/validator-ajv8": 5.14.3 + "@rjsf/core": 5.15.0 + "@rjsf/material-ui": 5.15.0 + "@rjsf/utils": 5.15.0 + "@rjsf/validator-ajv8": 5.15.0 "@testing-library/dom": ^9.0.0 "@testing-library/jest-dom": ^6.0.0 "@testing-library/react": ^14.0.0 @@ -8915,10 +8915,10 @@ __metadata: "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 "@react-hookz/web": ^23.0.0 - "@rjsf/core": 5.14.3 - "@rjsf/material-ui": 5.14.3 - "@rjsf/utils": 5.14.3 - "@rjsf/validator-ajv8": 5.14.3 + "@rjsf/core": 5.15.0 + "@rjsf/material-ui": 5.15.0 + "@rjsf/utils": 5.15.0 + "@rjsf/validator-ajv8": 5.15.0 "@testing-library/dom": ^9.0.0 "@testing-library/jest-dom": ^6.0.0 "@testing-library/react": ^14.0.0 @@ -15151,9 +15151,9 @@ __metadata: languageName: node linkType: hard -"@rjsf/core@npm:5.14.3": - version: 5.14.3 - resolution: "@rjsf/core@npm:5.14.3" +"@rjsf/core@npm:5.15.0": + version: 5.15.0 + resolution: "@rjsf/core@npm:5.15.0" dependencies: lodash: ^4.17.21 lodash-es: ^4.17.21 @@ -15163,20 +15163,20 @@ __metadata: peerDependencies: "@rjsf/utils": ^5.12.x react: ^16.14.0 || >=17 - checksum: 9929ae7b99f1c79dc108095c3338a30fe373cd0fc6c613f65d163f7729cda2509070bb7da581ce3ad068a41ea5050f4e8417508c12e53feb41c56119082d3aac + checksum: 430750dca4d96fa0bc48f8fbbb5c31f42df5cf9079a501d56449fe1428cf6087c7c45eb1846792f748cc52ce64ffb69aa2acf509ed5328b4c85d35dfaa7d3900 languageName: node linkType: hard -"@rjsf/material-ui@npm:5.14.3": - version: 5.14.3 - resolution: "@rjsf/material-ui@npm:5.14.3" +"@rjsf/material-ui@npm:5.15.0": + version: 5.15.0 + resolution: "@rjsf/material-ui@npm:5.15.0" peerDependencies: "@material-ui/core": ^4.12.3 "@material-ui/icons": ^4.11.2 "@rjsf/core": ^5.12.x "@rjsf/utils": ^5.12.x react: ^16.14.0 || >=17 - checksum: fa9b9a831fa333bb794ccde85f415c8daf18334d975a0f2aa1cd497017e7a03c398d5b4f4209eafd4aed4aa476578ef82e95cf544c5542ee030b080226f09388 + checksum: e36b1fd739128f60cd8b6f0ce04ccccaed7ef445d08cbd23bcad2dd16922fb881b303211085121b5444e6c9c9c826892c6fb1fc31d550cdc3b5a2068371e6506 languageName: node linkType: hard @@ -15195,9 +15195,9 @@ __metadata: languageName: node linkType: hard -"@rjsf/utils@npm:5.14.3": - version: 5.14.3 - resolution: "@rjsf/utils@npm:5.14.3" +"@rjsf/utils@npm:5.15.0": + version: 5.15.0 + resolution: "@rjsf/utils@npm:5.15.0" dependencies: json-schema-merge-allof: ^0.8.1 jsonpointer: ^5.0.1 @@ -15206,13 +15206,13 @@ __metadata: react-is: ^18.2.0 peerDependencies: react: ^16.14.0 || >=17 - checksum: 759f85e1d205d360024e569ab04c57543cbec4af8293636ba0af0ec7797bdcb361cd0b33c176ede464f101b33eb4240b60e241537ba19edefc04b91b80e6051e + checksum: 369de8620fdbd26aea074e0a33d5ea3b1bb89e3389d826a70612dbec8881617bb0dc8403ca6774d0def332ffe15d26bed133d6ff7361ff2978a4b024cea829c3 languageName: node linkType: hard -"@rjsf/validator-ajv8@npm:5.14.3": - version: 5.14.3 - resolution: "@rjsf/validator-ajv8@npm:5.14.3" +"@rjsf/validator-ajv8@npm:5.15.0": + version: 5.15.0 + resolution: "@rjsf/validator-ajv8@npm:5.15.0" dependencies: ajv: ^8.12.0 ajv-formats: ^2.1.1 @@ -15220,7 +15220,7 @@ __metadata: lodash-es: ^4.17.21 peerDependencies: "@rjsf/utils": ^5.12.x - checksum: 8b7caa0d5a81ecffaee1a538625c93ff8fdf860d67b80e75901df62112d00479bed6987c25427b84957b4e483c80c80d91713922bdb21ae8dd440242f0e8f5e3 + checksum: 1e703b711d9b8b22f4ad57477cad083b178763c5125369f98840914016e14a3c44534c8feee0388d88e0542becde18b64caf47ea19cd248cc28e263d8b7ba0f7 languageName: node linkType: hard From 3a9fbdbcd6b819fb32e5bbe6c40227f2840d6e44 Mon Sep 17 00:00:00 2001 From: Aramis Sennyey Date: Sat, 2 Dec 2023 11:43:40 -0500 Subject: [PATCH 052/275] fix: update the catalog client to prevent double encoding of filter query params Signed-off-by: Aramis Sennyey --- packages/catalog-client/src/CatalogClient.test.ts | 6 +++--- packages/catalog-client/src/CatalogClient.ts | 6 ++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/packages/catalog-client/src/CatalogClient.test.ts b/packages/catalog-client/src/CatalogClient.test.ts index 4892017032..745823471a 100644 --- a/packages/catalog-client/src/CatalogClient.test.ts +++ b/packages/catalog-client/src/CatalogClient.test.ts @@ -87,7 +87,7 @@ describe('CatalogClient', () => { server.use( rest.get(`${mockBaseUrl}/entities`, (req, res, ctx) => { expect(decodeURIComponent(req.url.search)).toBe( - '?filter=a=1,b=2,b=3,%C3%B6=%3D&filter=a=2&filter=c', + '?filter=a=1,b=2,b=3,ö==&filter=a=2&filter=c', ); return res(ctx.json([])); }), @@ -121,7 +121,7 @@ describe('CatalogClient', () => { server.use( rest.get(`${mockBaseUrl}/entities`, (req, res, ctx) => { expect(decodeURIComponent(req.url.search)).toBe( - '?filter=a=1,b=2,b=3,%C3%B6=%3D,c', + '?filter=a=1,b=2,b=3,ö==,c', ); return res(ctx.json([])); }), @@ -330,7 +330,7 @@ describe('CatalogClient', () => { expect(mockedEndpoint).toHaveBeenCalledTimes(1); expect( decodeURIComponent(mockedEndpoint.mock.calls[0][0].url.search), - ).toBe('?filter=a=1,b=2,b=3,%C3%B6=%3D&filter=a=2&filter=c'); + ).toBe('?filter=a=1,b=2,b=3,ö==&filter=a=2&filter=c'); }); it('should send query params correctly on initial request', async () => { diff --git a/packages/catalog-client/src/CatalogClient.ts b/packages/catalog-client/src/CatalogClient.ts index 511bf45c51..50219a0aa6 100644 --- a/packages/catalog-client/src/CatalogClient.ts +++ b/packages/catalog-client/src/CatalogClient.ts @@ -452,11 +452,9 @@ export class CatalogClient implements CatalogApi { for (const [key, value] of Object.entries(filterItem)) { for (const v of [value].flat()) { if (v === CATALOG_FILTER_EXISTS) { - filterParts.push(encodeURIComponent(key)); + filterParts.push(key); } else if (typeof v === 'string') { - filterParts.push( - `${encodeURIComponent(key)}=${encodeURIComponent(v)}`, - ); + filterParts.push(`${key}=${v}`); } } } From 82fa88be3b7edbc19e72eb1c8fad7ea98d113f9c Mon Sep 17 00:00:00 2001 From: Aramis Sennyey Date: Sat, 2 Dec 2023 11:47:06 -0500 Subject: [PATCH 053/275] add changeset Signed-off-by: Aramis Sennyey --- .changeset/strange-brooms-poke.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/strange-brooms-poke.md diff --git a/.changeset/strange-brooms-poke.md b/.changeset/strange-brooms-poke.md new file mode 100644 index 0000000000..0c0e4d69a1 --- /dev/null +++ b/.changeset/strange-brooms-poke.md @@ -0,0 +1,5 @@ +--- +'@backstage/catalog-client': patch +--- + +Fixes a bug where `filter` query parameters were double URL encoded. From 621afaab10e1429263815261e38f89ac3ee20309 Mon Sep 17 00:00:00 2001 From: Aramis Sennyey Date: Sat, 2 Dec 2023 13:55:06 -0500 Subject: [PATCH 054/275] add a new test for url unsafe values Signed-off-by: Aramis Sennyey --- .../catalog-client/src/CatalogClient.test.ts | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/packages/catalog-client/src/CatalogClient.test.ts b/packages/catalog-client/src/CatalogClient.test.ts index 745823471a..1ade3f7170 100644 --- a/packages/catalog-client/src/CatalogClient.test.ts +++ b/packages/catalog-client/src/CatalogClient.test.ts @@ -333,6 +333,47 @@ describe('CatalogClient', () => { ).toBe('?filter=a=1,b=2,b=3,ö==&filter=a=2&filter=c'); }); + it('builds search filters property even those with URL unsafe values', async () => { + const mockedEndpoint = jest + .fn() + .mockImplementation((_req, res, ctx) => + res(ctx.json({ items: [], totalItems: 0 })), + ); + + server.use(rest.get(`${mockBaseUrl}/entities/by-query`, mockedEndpoint)); + + const response = await client.queryEntities( + { + filter: [ + { + 'metadata.annotation?test': 'backstage.io/test&test123?test=123', + a: '2', + b: ['1, 2', '3'], + }, + { + 'my-name test': 't%^url*encoded', + 'my-name test2': ['t%^url*encoded2', 'url'], + }, + { + c: CATALOG_FILTER_EXISTS, + }, + ], + }, + { token }, + ); + + expect(response).toEqual({ items: [], totalItems: 0 }); + expect(mockedEndpoint).toHaveBeenCalledTimes(1); + expect(mockedEndpoint.mock.calls[0][0].url.search).toBe( + '?filter=metadata.annotation%3Ftest%3Dbackstage.io%2Ftest%26test123%3Ftest%3D123%2Ca%3D2%2Cb%3D1%2C%202%2Cb%3D3&filter=my-name%20test%3Dt%25%5Eurl%2Aencoded%2Cmy-name%20test2%3Dt%25%5Eurl%2Aencoded2%2Cmy-name%20test2%3Durl&filter=c', + ); + expect( + decodeURIComponent(mockedEndpoint.mock.calls[0][0].url.search), + ).toBe( + '?filter=metadata.annotation?test=backstage.io/test&test123?test=123,a=2,b=1, 2,b=3&filter=my-name test=t%^url*encoded,my-name test2=t%^url*encoded2,my-name test2=url&filter=c', + ); + }); + it('should send query params correctly on initial request', async () => { const mockedEndpoint = jest .fn() From f3e44b73e0317d55cd924b09a60ddb65877f0e02 Mon Sep 17 00:00:00 2001 From: Aramis Sennyey Date: Sat, 2 Dec 2023 14:00:31 -0500 Subject: [PATCH 055/275] make the test case a little smaller Signed-off-by: Aramis Sennyey --- .../catalog-client/src/CatalogClient.test.ts | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/packages/catalog-client/src/CatalogClient.test.ts b/packages/catalog-client/src/CatalogClient.test.ts index 1ade3f7170..f8bb6660c7 100644 --- a/packages/catalog-client/src/CatalogClient.test.ts +++ b/packages/catalog-client/src/CatalogClient.test.ts @@ -346,16 +346,8 @@ describe('CatalogClient', () => { { filter: [ { - 'metadata.annotation?test': 'backstage.io/test&test123?test=123', - a: '2', - b: ['1, 2', '3'], - }, - { - 'my-name test': 't%^url*encoded', - 'my-name test2': ['t%^url*encoded2', 'url'], - }, - { - c: CATALOG_FILTER_EXISTS, + '!@#$%': 't?i=1&a:2', + '^&*(){}[]': ['t%^url*encoded2', 'url'], }, ], }, @@ -364,14 +356,15 @@ describe('CatalogClient', () => { expect(response).toEqual({ items: [], totalItems: 0 }); expect(mockedEndpoint).toHaveBeenCalledTimes(1); + // Validate that the URL is _actually_ encoded. expect(mockedEndpoint.mock.calls[0][0].url.search).toBe( - '?filter=metadata.annotation%3Ftest%3Dbackstage.io%2Ftest%26test123%3Ftest%3D123%2Ca%3D2%2Cb%3D1%2C%202%2Cb%3D3&filter=my-name%20test%3Dt%25%5Eurl%2Aencoded%2Cmy-name%20test2%3Dt%25%5Eurl%2Aencoded2%2Cmy-name%20test2%3Durl&filter=c', + '?filter=%21%40%23%24%25%3Dt%3Fi%3D1%26a%3A2%2C%5E%26%2A%28%29%7B%7D%5B%5D%3Dt%25%5Eurl%2Aencoded2%2C%5E%26%2A%28%29%7B%7D%5B%5D%3Durl', ); + + // Validate that the URL matches the expected decoded value. expect( decodeURIComponent(mockedEndpoint.mock.calls[0][0].url.search), - ).toBe( - '?filter=metadata.annotation?test=backstage.io/test&test123?test=123,a=2,b=1, 2,b=3&filter=my-name test=t%^url*encoded,my-name test2=t%^url*encoded2,my-name test2=url&filter=c', - ); + ).toBe('?filter=!@#$%=t?i=1&a:2,^&*(){}[]=t%^url*encoded2,^&*(){}[]=url'); }); it('should send query params correctly on initial request', async () => { From e7c59fcbae5031b7e4d241dcfb90ec37ed72088f Mon Sep 17 00:00:00 2001 From: Aramis Sennyey Date: Sat, 2 Dec 2023 14:21:17 -0500 Subject: [PATCH 056/275] Fix URI encoding for other parameters as well and adjust tests. Signed-off-by: Aramis Sennyey --- .../catalog-client/src/CatalogClient.test.ts | 45 +++++++++++++++++-- packages/catalog-client/src/CatalogClient.ts | 14 +++--- 2 files changed, 47 insertions(+), 12 deletions(-) diff --git a/packages/catalog-client/src/CatalogClient.test.ts b/packages/catalog-client/src/CatalogClient.test.ts index f8bb6660c7..5cfb563d9f 100644 --- a/packages/catalog-client/src/CatalogClient.test.ts +++ b/packages/catalog-client/src/CatalogClient.test.ts @@ -142,12 +142,47 @@ describe('CatalogClient', () => { expect(response.items).toEqual([]); }); + it('builds search filters property even those with URL unsafe values', async () => { + const mockedEndpoint = jest + .fn() + .mockImplementation((_req, res, ctx) => + res(ctx.json({ items: [], totalItems: 0 })), + ); + + server.use(rest.get(`${mockBaseUrl}/entities/by-query`, mockedEndpoint)); + + const response = await client.queryEntities( + { + filter: [ + { + '!@#$%': 't?i=1&a:2', + '^&*(){}[]': ['t%^url*encoded2', 'url'], + }, + ], + }, + { token }, + ); + + expect(response).toEqual({ items: [], totalItems: 0 }); + expect(mockedEndpoint).toHaveBeenCalledTimes(1); + // Validate that the URL is _actually_ encoded. + expect(mockedEndpoint.mock.calls[0][0].url.search).toBe( + '?filter=%21%40%23%24%25%3Dt%3Fi%3D1%26a%3A2%2C%5E%26%2A%28%29%7B%7D%5B%5D%3Dt%25%5Eurl%2Aencoded2%2C%5E%26%2A%28%29%7B%7D%5B%5D%3Durl', + ); + + // Validate that the URL matches the expected decoded value. + expect( + decodeURIComponent(mockedEndpoint.mock.calls[0][0].url.search), + ).toBe('?filter=!@#$%=t?i=1&a:2,^&*(){}[]=t%^url*encoded2,^&*(){}[]=url'); + }); + it('builds entity field selectors properly', async () => { - expect.assertions(2); + expect.assertions(3); server.use( rest.get(`${mockBaseUrl}/entities`, (req, res, ctx) => { - expect(decodeURIComponent(req.url.search)).toBe('?fields=a.b,%C3%B6'); + expect(req.url.search).toBe('?fields=a.b,%C3%B6'); + expect(decodeURIComponent(req.url.search)).toBe('?fields=a.b,ö'); return res(ctx.json([])); }), ); @@ -387,10 +422,14 @@ describe('CatalogClient', () => { { field: 'metadata.uid', order: 'desc' }, ], }); + // Verify we actually encode the URI. + expect(mockedEndpoint.mock.calls[0][0].url.search).toBe( + '?fields=a,b&limit=100&orderField=metadata.name%2Casc&orderField=metadata.uid%2Cdesc&fullTextFilterTerm=query', + ); expect( decodeURIComponent(mockedEndpoint.mock.calls[0][0].url.search), ).toBe( - '?fields=a,b&limit=100&orderField=metadata.name%2Casc&orderField=metadata.uid%2Cdesc&fullTextFilterTerm=query', + '?fields=a,b&limit=100&orderField=metadata.name,asc&orderField=metadata.uid,desc&fullTextFilterTerm=query', ); }); diff --git a/packages/catalog-client/src/CatalogClient.ts b/packages/catalog-client/src/CatalogClient.ts index 50219a0aa6..8409e655c0 100644 --- a/packages/catalog-client/src/CatalogClient.ts +++ b/packages/catalog-client/src/CatalogClient.ts @@ -107,11 +107,7 @@ export class CatalogClient implements CatalogApi { if (order) { for (const directive of [order].flat()) { if (directive) { - encodedOrder.push( - `${encodeURIComponent(directive.order)}:${encodeURIComponent( - directive.field, - )}`, - ); + encodedOrder.push(`${directive.order}:${directive.field}`); } } } @@ -120,7 +116,7 @@ export class CatalogClient implements CatalogApi { await this.apiClient.getEntities( { query: { - fields: fields.map(encodeURIComponent), + fields: fields, limit, filter: this.getFilterValue(filter), offset, @@ -209,10 +205,10 @@ export class CatalogClient implements CatalogApi { if (orderFields !== undefined) { params.orderField = ( Array.isArray(orderFields) ? orderFields : [orderFields] - ).map(({ field, order }) => encodeURIComponent(`${field},${order}`)); + ).map(({ field, order }) => `${field},${order}`); } if (fields.length) { - params.fields = fields.map(encodeURIComponent); + params.fields = fields; } const normalizedFullTextFilterTerm = fullTextFilter?.term?.trim(); @@ -230,7 +226,7 @@ export class CatalogClient implements CatalogApi { params.limit = limit; } if (fields.length) { - params.fields = fields.map(encodeURIComponent); + params.fields = fields; } } From b24742ad9f058412726119f8e18a2bb071bae5ab Mon Sep 17 00:00:00 2001 From: Aramis Sennyey Date: Sat, 2 Dec 2023 14:27:52 -0500 Subject: [PATCH 057/275] add more checks in the tests for both URL encoding and decoding Signed-off-by: Aramis Sennyey --- .../catalog-client/src/CatalogClient.test.ts | 34 +++++++++++++++++-- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/packages/catalog-client/src/CatalogClient.test.ts b/packages/catalog-client/src/CatalogClient.test.ts index 5cfb563d9f..f15d695d54 100644 --- a/packages/catalog-client/src/CatalogClient.test.ts +++ b/packages/catalog-client/src/CatalogClient.test.ts @@ -82,10 +82,16 @@ describe('CatalogClient', () => { }); it('builds multiple entity search filters properly', async () => { - expect.assertions(2); + expect.assertions(3); server.use( rest.get(`${mockBaseUrl}/entities`, (req, res, ctx) => { + // Validate that the URL is _actually_ encoded. + expect(req.url.search).toBe( + '?filter=a%3D1%2Cb%3D2%2Cb%3D3%2C%C3%B6%3D%3D&filter=a%3D2&filter=c', + ); + + // Validate that the decoded URL matches the expected value. expect(decodeURIComponent(req.url.search)).toBe( '?filter=a=1,b=2,b=3,ö==&filter=a=2&filter=c', ); @@ -116,10 +122,16 @@ describe('CatalogClient', () => { }); it('builds single entity search filter properly', async () => { - expect.assertions(2); + expect.assertions(3); server.use( rest.get(`${mockBaseUrl}/entities`, (req, res, ctx) => { + // Validate that the URL is actually encoded. + expect(req.url.search).toBe( + '?filter=a%3D1%2Cb%3D2%2Cb%3D3%2C%C3%B6%3D%3D%2Cc', + ); + + // Validate that the decoded URL matches the expected value. expect(decodeURIComponent(req.url.search)).toBe( '?filter=a=1,b=2,b=3,ö==,c', ); @@ -181,7 +193,10 @@ describe('CatalogClient', () => { server.use( rest.get(`${mockBaseUrl}/entities`, (req, res, ctx) => { + // Validate that the URL is _actually_ encoded. expect(req.url.search).toBe('?fields=a.b,%C3%B6'); + + // Validate that the URL matches the expected decoded value. expect(decodeURIComponent(req.url.search)).toBe('?fields=a.b,ö'); return res(ctx.json([])); }), @@ -236,10 +251,16 @@ describe('CatalogClient', () => { }); it('handles ordering properly', async () => { - expect.assertions(2); + expect.assertions(3); server.use( rest.get(`${mockBaseUrl}/entities`, (req, res, ctx) => { + // Validate that the URL is _actually_ encoded. + expect(req.url.search).toBe( + '?order=asc%3Akind&order=desc%3Ametadata.name', + ); + + // Validate that the URL matches the expected value. expect(decodeURIComponent(req.url.search)).toBe( '?order=asc:kind&order=desc:metadata.name', ); @@ -363,6 +384,13 @@ describe('CatalogClient', () => { expect(response).toEqual({ items: [], totalItems: 0 }); expect(mockedEndpoint).toHaveBeenCalledTimes(1); + + // Validate that the URL is _actually_ encoded. + expect(mockedEndpoint.mock.calls[0][0].url.search).toBe( + '?filter=a%3D1%2Cb%3D2%2Cb%3D3%2C%C3%B6%3D%3D&filter=a%3D2&filter=c', + ); + + // Validate that the decoded URL matches the expected value. expect( decodeURIComponent(mockedEndpoint.mock.calls[0][0].url.search), ).toBe('?filter=a=1,b=2,b=3,ö==&filter=a=2&filter=c'); From bd882e443e1811c71c1ca28314ef06e6c5ae68b3 Mon Sep 17 00:00:00 2001 From: Aramis Sennyey Date: Sat, 2 Dec 2023 14:29:21 -0500 Subject: [PATCH 058/275] quick syntax thing Signed-off-by: Aramis Sennyey --- packages/catalog-client/src/CatalogClient.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/catalog-client/src/CatalogClient.ts b/packages/catalog-client/src/CatalogClient.ts index 8409e655c0..f97360d1d7 100644 --- a/packages/catalog-client/src/CatalogClient.ts +++ b/packages/catalog-client/src/CatalogClient.ts @@ -116,7 +116,7 @@ export class CatalogClient implements CatalogApi { await this.apiClient.getEntities( { query: { - fields: fields, + fields, limit, filter: this.getFilterValue(filter), offset, From 634f62065f290b663e310615657ac847f348b7e2 Mon Sep 17 00:00:00 2001 From: Aramis Sennyey Date: Sat, 2 Dec 2023 14:48:59 -0500 Subject: [PATCH 059/275] use URLSearchParams instead of string comps Signed-off-by: Aramis Sennyey --- .../catalog-client/src/CatalogClient.test.ts | 115 +++++++----------- 1 file changed, 47 insertions(+), 68 deletions(-) diff --git a/packages/catalog-client/src/CatalogClient.test.ts b/packages/catalog-client/src/CatalogClient.test.ts index f15d695d54..b8212fde96 100644 --- a/packages/catalog-client/src/CatalogClient.test.ts +++ b/packages/catalog-client/src/CatalogClient.test.ts @@ -82,19 +82,16 @@ describe('CatalogClient', () => { }); it('builds multiple entity search filters properly', async () => { - expect.assertions(3); + expect.assertions(2); server.use( rest.get(`${mockBaseUrl}/entities`, (req, res, ctx) => { - // Validate that the URL is _actually_ encoded. - expect(req.url.search).toBe( - '?filter=a%3D1%2Cb%3D2%2Cb%3D3%2C%C3%B6%3D%3D&filter=a%3D2&filter=c', - ); - - // Validate that the decoded URL matches the expected value. - expect(decodeURIComponent(req.url.search)).toBe( - '?filter=a=1,b=2,b=3,ö==&filter=a=2&filter=c', - ); + const queryParams = new URLSearchParams(req.url.search); + expect(queryParams.getAll('filter')).toEqual([ + 'a=1,b=2,b=3,ö==', + 'a=2', + 'c', + ]); return res(ctx.json([])); }), ); @@ -122,19 +119,12 @@ describe('CatalogClient', () => { }); it('builds single entity search filter properly', async () => { - expect.assertions(3); + expect.assertions(2); server.use( rest.get(`${mockBaseUrl}/entities`, (req, res, ctx) => { - // Validate that the URL is actually encoded. - expect(req.url.search).toBe( - '?filter=a%3D1%2Cb%3D2%2Cb%3D3%2C%C3%B6%3D%3D%2Cc', - ); - - // Validate that the decoded URL matches the expected value. - expect(decodeURIComponent(req.url.search)).toBe( - '?filter=a=1,b=2,b=3,ö==,c', - ); + const queryParams = new URLSearchParams(req.url.search); + expect(queryParams.getAll('filter')).toEqual(['a=1,b=2,b=3,ö==,c']); return res(ctx.json([])); }), ); @@ -177,27 +167,22 @@ describe('CatalogClient', () => { expect(response).toEqual({ items: [], totalItems: 0 }); expect(mockedEndpoint).toHaveBeenCalledTimes(1); - // Validate that the URL is _actually_ encoded. - expect(mockedEndpoint.mock.calls[0][0].url.search).toBe( - '?filter=%21%40%23%24%25%3Dt%3Fi%3D1%26a%3A2%2C%5E%26%2A%28%29%7B%7D%5B%5D%3Dt%25%5Eurl%2Aencoded2%2C%5E%26%2A%28%29%7B%7D%5B%5D%3Durl', - ); - // Validate that the URL matches the expected decoded value. - expect( - decodeURIComponent(mockedEndpoint.mock.calls[0][0].url.search), - ).toBe('?filter=!@#$%=t?i=1&a:2,^&*(){}[]=t%^url*encoded2,^&*(){}[]=url'); + const queryParams = new URLSearchParams( + mockedEndpoint.mock.calls[0][0].url.search, + ); + expect(queryParams.getAll('filter')).toEqual([ + '!@#$%=t?i=1&a:2,^&*(){}[]=t%^url*encoded2,^&*(){}[]=url', + ]); }); it('builds entity field selectors properly', async () => { - expect.assertions(3); + expect.assertions(2); server.use( rest.get(`${mockBaseUrl}/entities`, (req, res, ctx) => { - // Validate that the URL is _actually_ encoded. - expect(req.url.search).toBe('?fields=a.b,%C3%B6'); - - // Validate that the URL matches the expected decoded value. - expect(decodeURIComponent(req.url.search)).toBe('?fields=a.b,ö'); + const queryParams = new URLSearchParams(req.url.search); + expect(queryParams.getAll('fields')).toEqual(['a.b,ö']); return res(ctx.json([])); }), ); @@ -251,19 +236,15 @@ describe('CatalogClient', () => { }); it('handles ordering properly', async () => { - expect.assertions(3); + expect.assertions(2); server.use( rest.get(`${mockBaseUrl}/entities`, (req, res, ctx) => { - // Validate that the URL is _actually_ encoded. - expect(req.url.search).toBe( - '?order=asc%3Akind&order=desc%3Ametadata.name', - ); - - // Validate that the URL matches the expected value. - expect(decodeURIComponent(req.url.search)).toBe( - '?order=asc:kind&order=desc:metadata.name', - ); + const queryParams = new URLSearchParams(req.url.search); + expect(queryParams.getAll('order')).toEqual([ + 'asc:kind', + 'desc:metadata.name', + ]); return res(ctx.json([])); }), ); @@ -385,15 +366,14 @@ describe('CatalogClient', () => { expect(response).toEqual({ items: [], totalItems: 0 }); expect(mockedEndpoint).toHaveBeenCalledTimes(1); - // Validate that the URL is _actually_ encoded. - expect(mockedEndpoint.mock.calls[0][0].url.search).toBe( - '?filter=a%3D1%2Cb%3D2%2Cb%3D3%2C%C3%B6%3D%3D&filter=a%3D2&filter=c', + const queryParams = new URLSearchParams( + mockedEndpoint.mock.calls[0][0].url.search, ); - - // Validate that the decoded URL matches the expected value. - expect( - decodeURIComponent(mockedEndpoint.mock.calls[0][0].url.search), - ).toBe('?filter=a=1,b=2,b=3,ö==&filter=a=2&filter=c'); + expect(queryParams.getAll('filter')).toEqual([ + 'a=1,b=2,b=3,ö==', + 'a=2', + 'c', + ]); }); it('builds search filters property even those with URL unsafe values', async () => { @@ -419,15 +399,12 @@ describe('CatalogClient', () => { expect(response).toEqual({ items: [], totalItems: 0 }); expect(mockedEndpoint).toHaveBeenCalledTimes(1); - // Validate that the URL is _actually_ encoded. - expect(mockedEndpoint.mock.calls[0][0].url.search).toBe( - '?filter=%21%40%23%24%25%3Dt%3Fi%3D1%26a%3A2%2C%5E%26%2A%28%29%7B%7D%5B%5D%3Dt%25%5Eurl%2Aencoded2%2C%5E%26%2A%28%29%7B%7D%5B%5D%3Durl', + const queryParams = new URLSearchParams( + mockedEndpoint.mock.calls[0][0].url.search, ); - - // Validate that the URL matches the expected decoded value. - expect( - decodeURIComponent(mockedEndpoint.mock.calls[0][0].url.search), - ).toBe('?filter=!@#$%=t?i=1&a:2,^&*(){}[]=t%^url*encoded2,^&*(){}[]=url'); + expect(queryParams.getAll('filter')).toEqual([ + '!@#$%=t?i=1&a:2,^&*(){}[]=t%^url*encoded2,^&*(){}[]=url', + ]); }); it('should send query params correctly on initial request', async () => { @@ -450,15 +427,17 @@ describe('CatalogClient', () => { { field: 'metadata.uid', order: 'desc' }, ], }); - // Verify we actually encode the URI. - expect(mockedEndpoint.mock.calls[0][0].url.search).toBe( - '?fields=a,b&limit=100&orderField=metadata.name%2Casc&orderField=metadata.uid%2Cdesc&fullTextFilterTerm=query', - ); - expect( - decodeURIComponent(mockedEndpoint.mock.calls[0][0].url.search), - ).toBe( - '?fields=a,b&limit=100&orderField=metadata.name,asc&orderField=metadata.uid,desc&fullTextFilterTerm=query', + + const queryParams = new URLSearchParams( + mockedEndpoint.mock.calls[0][0].url.search, ); + expect(queryParams.getAll('fields')).toEqual(['a,b']); + expect(queryParams.getAll('limit')).toEqual(['100']); + expect(queryParams.getAll('fullTextFilterTerm')).toEqual(['query']); + expect(queryParams.getAll('orderField')).toEqual([ + 'metadata.name,asc', + 'metadata.uid,desc', + ]); }); it('should ignore initial query params if cursor is passed', async () => { From 28361b6c4d9a1c36d7cf946c8244e0a6dbcd648d Mon Sep 17 00:00:00 2001 From: Aramis <34432188+sennyeya@users.noreply.github.com> Date: Sat, 2 Dec 2023 15:08:45 -0500 Subject: [PATCH 060/275] Update strange-brooms-poke.md Signed-off-by: Aramis <34432188+sennyeya@users.noreply.github.com> --- .changeset/strange-brooms-poke.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/strange-brooms-poke.md b/.changeset/strange-brooms-poke.md index 0c0e4d69a1..35b7d48360 100644 --- a/.changeset/strange-brooms-poke.md +++ b/.changeset/strange-brooms-poke.md @@ -2,4 +2,4 @@ '@backstage/catalog-client': patch --- -Fixes a bug where `filter` query parameters were double URL encoded. +Fixes a bug where some query parameters were double URL encoded. From a96c2d47f8eac232c1cebebd68abf0bad56c0ae2 Mon Sep 17 00:00:00 2001 From: Kurt King Date: Sat, 2 Dec 2023 20:53:02 -0700 Subject: [PATCH 061/275] feat: display links card for groups by default Signed-off-by: Kurt King --- .changeset/quick-lions-care.md | 5 +++++ packages/app/src/components/catalog/EntityPage.tsx | 5 ++++- .../packages/app/src/components/catalog/EntityPage.tsx | 5 ++++- 3 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 .changeset/quick-lions-care.md diff --git a/.changeset/quick-lions-care.md b/.changeset/quick-lions-care.md new file mode 100644 index 0000000000..aa5caada05 --- /dev/null +++ b/.changeset/quick-lions-care.md @@ -0,0 +1,5 @@ +--- +'@backstage/create-app': patch +--- + +Include the `` for group entities by default diff --git a/packages/app/src/components/catalog/EntityPage.tsx b/packages/app/src/components/catalog/EntityPage.tsx index 3bd8869f4f..8c9eab20d9 100644 --- a/packages/app/src/components/catalog/EntityPage.tsx +++ b/packages/app/src/components/catalog/EntityPage.tsx @@ -792,13 +792,16 @@ const groupPage = ( + + + - + diff --git a/packages/create-app/templates/default-app/packages/app/src/components/catalog/EntityPage.tsx b/packages/create-app/templates/default-app/packages/app/src/components/catalog/EntityPage.tsx index 6722ea2d03..d6ee8c3152 100644 --- a/packages/create-app/templates/default-app/packages/app/src/components/catalog/EntityPage.tsx +++ b/packages/create-app/templates/default-app/packages/app/src/components/catalog/EntityPage.tsx @@ -297,10 +297,13 @@ const groupPage = ( + + + - + From 24eec9f5d5b029db7197fe7ac7f8a6405ce9182d Mon Sep 17 00:00:00 2001 From: Kurt King Date: Sun, 3 Dec 2023 12:23:56 -0700 Subject: [PATCH 062/275] refactor: put links after members and ownership Signed-off-by: Kurt King --- packages/app/src/components/catalog/EntityPage.tsx | 6 +++--- .../packages/app/src/components/catalog/EntityPage.tsx | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/app/src/components/catalog/EntityPage.tsx b/packages/app/src/components/catalog/EntityPage.tsx index 8c9eab20d9..4d5f65cbbe 100644 --- a/packages/app/src/components/catalog/EntityPage.tsx +++ b/packages/app/src/components/catalog/EntityPage.tsx @@ -792,9 +792,6 @@ const groupPage = ( - - - + + + diff --git a/packages/create-app/templates/default-app/packages/app/src/components/catalog/EntityPage.tsx b/packages/create-app/templates/default-app/packages/app/src/components/catalog/EntityPage.tsx index d6ee8c3152..7c6a71e070 100644 --- a/packages/create-app/templates/default-app/packages/app/src/components/catalog/EntityPage.tsx +++ b/packages/create-app/templates/default-app/packages/app/src/components/catalog/EntityPage.tsx @@ -297,15 +297,15 @@ const groupPage = ( - - - + + + From d5ab1b32dbb159b67ba6916a8384e64e01672ebd Mon Sep 17 00:00:00 2001 From: blam Date: Mon, 4 Dec 2023 14:50:33 +0100 Subject: [PATCH 063/275] fix: scaffolder module should depend on -node library Signed-off-by: blam --- packages/cli/templates/scaffolder-module/package.json.hbs | 2 +- .../templates/scaffolder-module/src/actions/example/example.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cli/templates/scaffolder-module/package.json.hbs b/packages/cli/templates/scaffolder-module/package.json.hbs index 618e953b74..0ebe5dd5f4 100644 --- a/packages/cli/templates/scaffolder-module/package.json.hbs +++ b/packages/cli/templates/scaffolder-module/package.json.hbs @@ -29,7 +29,7 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/plugin-scaffolder-backend": "{{versionQuery '@backstage/plugin-scaffolder-backend'}}" + "@backstage/plugin-scaffolder-node": "{{versionQuery '@backstage/plugin-scaffolder-node'}}" }, "devDependencies": { "@backstage/backend-common": "{{versionQuery '@backstage/backend-common'}}", diff --git a/packages/cli/templates/scaffolder-module/src/actions/example/example.ts b/packages/cli/templates/scaffolder-module/src/actions/example/example.ts index c04132e755..2b05c7fe38 100644 --- a/packages/cli/templates/scaffolder-module/src/actions/example/example.ts +++ b/packages/cli/templates/scaffolder-module/src/actions/example/example.ts @@ -1,4 +1,4 @@ -import { createTemplateAction } from '@backstage/plugin-scaffolder-backend'; +import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; /** * Creates an `acme:example` Scaffolder action. From 7115a27f70c59c5e86eb385c0970943b6aef5bb4 Mon Sep 17 00:00:00 2001 From: Taras Mankovski Date: Mon, 4 Dec 2023 18:08:01 -0500 Subject: [PATCH 064/275] Remove templateDir to prevent openapitools from attempting to read it Signed-off-by: Taras Mankovski --- packages/repo-tools/templates/typescript-backstage.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/repo-tools/templates/typescript-backstage.yaml b/packages/repo-tools/templates/typescript-backstage.yaml index eaa72d7179..310a21e75a 100644 --- a/packages/repo-tools/templates/typescript-backstage.yaml +++ b/packages/repo-tools/templates/typescript-backstage.yaml @@ -1,5 +1,3 @@ -templateDir: templates/typescript-backstage - files: api.mustache: templateType: API @@ -15,4 +13,4 @@ files: destinationFilename: apis/index.ts pluginId.mustache: templateType: SupportingFiles - destinationFilename: pluginId.ts \ No newline at end of file + destinationFilename: pluginId.ts From 91e231d34000f22fd133442a5606002157a24b56 Mon Sep 17 00:00:00 2001 From: Taras Mankovski Date: Mon, 4 Dec 2023 18:09:57 -0500 Subject: [PATCH 065/275] Do not use yarn to execute openapi-generator-cli binary Signed-off-by: Taras Mankovski --- .../src/commands/openapi/client/generate.ts | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/packages/repo-tools/src/commands/openapi/client/generate.ts b/packages/repo-tools/src/commands/openapi/client/generate.ts index 5efd4dadd9..8d85e9cd67 100644 --- a/packages/repo-tools/src/commands/openapi/client/generate.ts +++ b/packages/repo-tools/src/commands/openapi/client/generate.ts @@ -36,10 +36,9 @@ async function generate(spec: string, outputDirectory: string) { ); await exec( - // The actual main.js file for the binary isn't executable but yarn does _something_ to make it executable. - // TODO (sennyeya@): Make this use the actual binary - `yarn openapi-generator-cli`, + 'node', [ + resolvePackagePath('@openapitools/openapi-generator-cli', 'main.js'), 'generate', '-i', resolvedOpenapiPath, @@ -62,10 +61,8 @@ async function generate(spec: string, outputDirectory: string) { ], { maxBuffer: Number.MAX_VALUE, - cwd: cliPaths.ownDir, env: { ...process.env, - // PWD: outputDirectory, }, }, ); @@ -74,8 +71,9 @@ async function generate(spec: string, outputDirectory: string) { `yarn backstage-cli package lint --fix ${resolvedOutputDirectory}`, ); - if (cliPaths.resolveTargetRoot('node_modules/.bin/prettier')) { - await exec(`yarn prettier --write ${resolvedOutputDirectory}`); + const prettier = cliPaths.resolveTargetRoot('node_modules/.bin/prettier'); + if (prettier) { + await exec(`${prettier} --write ${resolvedOutputDirectory}`); } fs.removeSync(resolve(resolvedOutputDirectory, '.openapi-generator-ignore')); From 45bfb204231994c896dccebf450c0eaf375df58d Mon Sep 17 00:00:00 2001 From: Taras Mankovski Date: Mon, 4 Dec 2023 18:28:19 -0500 Subject: [PATCH 066/275] Added changeset Signed-off-by: Taras Mankovski --- .changeset/spotty-terms-occur.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/spotty-terms-occur.md diff --git a/.changeset/spotty-terms-occur.md b/.changeset/spotty-terms-occur.md new file mode 100644 index 0000000000..923cd04beb --- /dev/null +++ b/.changeset/spotty-terms-occur.md @@ -0,0 +1,5 @@ +--- +'@backstage/repo-tools': patch +--- + +No longer using yarn to execute openapi-generator-cli and prettier in `repo-tools openapi generate-client` From 82fb18b11d9220d232fc2adafd3b6109a12f714f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 5 Dec 2023 00:43:36 +0000 Subject: [PATCH 067/275] fix(deps): update dependency @asyncapi/react-component to v1.2.6 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .changeset/renovate-5644299.md | 5 + plugins/api-docs/package.json | 2 +- yarn.lock | 184 +++++++-------------------------- 3 files changed, 42 insertions(+), 149 deletions(-) create mode 100644 .changeset/renovate-5644299.md diff --git a/.changeset/renovate-5644299.md b/.changeset/renovate-5644299.md new file mode 100644 index 0000000000..04ba4c47a4 --- /dev/null +++ b/.changeset/renovate-5644299.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-api-docs': patch +--- + +Updated dependency `@asyncapi/react-component` to `1.2.6`. diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json index 30b8650e19..01c165f6a1 100644 --- a/plugins/api-docs/package.json +++ b/plugins/api-docs/package.json @@ -33,7 +33,7 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@asyncapi/react-component": "1.2.2", + "@asyncapi/react-component": "1.2.6", "@backstage/catalog-model": "workspace:^", "@backstage/core-components": "workspace:^", "@backstage/core-plugin-api": "workspace:^", diff --git a/yarn.lock b/yarn.lock index 2fd28cd48c..628ea1fe29 100644 --- a/yarn.lock +++ b/yarn.lock @@ -138,35 +138,35 @@ __metadata: languageName: node linkType: hard -"@asyncapi/avro-schema-parser@npm:^3.0.5": - version: 3.0.5 - resolution: "@asyncapi/avro-schema-parser@npm:3.0.5" +"@asyncapi/avro-schema-parser@npm:^3.0.7": + version: 3.0.7 + resolution: "@asyncapi/avro-schema-parser@npm:3.0.7" dependencies: - "@asyncapi/parser": ^2.1.2 + "@asyncapi/parser": ^3.0.1 "@types/json-schema": ^7.0.11 avsc: ^5.7.6 - checksum: c8e0a5aac1a5793ab92af44f67416273a8c5a61336785a6d6963ea80402f4b6c6129e1deff6f4e1a09aa31b3e311203bf8c08fb9f3aa9f01114c1b558f3a74f3 + checksum: c7755708161f41812ebee90c92fb721176230f0006ddd01683b72c7c1d484a6c5cbe7d7e59c54a5c7221f5f722388642ec26b19a67adc9d30059067cc4276d69 languageName: node linkType: hard -"@asyncapi/openapi-schema-parser@npm:^3.0.6": - version: 3.0.6 - resolution: "@asyncapi/openapi-schema-parser@npm:3.0.6" +"@asyncapi/openapi-schema-parser@npm:^3.0.8": + version: 3.0.8 + resolution: "@asyncapi/openapi-schema-parser@npm:3.0.8" dependencies: - "@asyncapi/parser": ^2.1.2 + "@asyncapi/parser": ^3.0.1 "@openapi-contrib/openapi-schema-to-json-schema": ~3.2.0 ajv: ^8.11.0 ajv-errors: ^3.0.0 ajv-formats: ^2.1.1 - checksum: d02174ff44d9f863e54c80f96bc95f96f8eeb491843ecc89ba92222d3e77e6f1593c370d83208b70360a0843a56cc35d23ca559c196dba1eb14a8b62e25d6a55 + checksum: 9c3f49d1a826818b864b2a0b16144d88eb2ecf7ca1d9c1e8554eac30d9875619638924892d093f0270b6b9a04efca1a8918dd5a7eb13fd88c14183d467af5ceb languageName: node linkType: hard -"@asyncapi/parser@npm:^2.1.0, @asyncapi/parser@npm:^2.1.2": - version: 2.1.2 - resolution: "@asyncapi/parser@npm:2.1.2" +"@asyncapi/parser@npm:^3.0.1": + version: 3.0.1 + resolution: "@asyncapi/parser@npm:3.0.1" dependencies: - "@asyncapi/specs": ^5.1.0 + "@asyncapi/specs": ^6.1.0 "@openapi-contrib/openapi-schema-to-json-schema": ~3.2.0 "@stoplight/json": ^3.20.2 "@stoplight/json-ref-readers": ^1.2.2 @@ -185,54 +185,29 @@ __metadata: js-yaml: ^4.1.0 jsonpath-plus: ^7.2.0 node-fetch: 2.6.7 - checksum: fb88d211455937bccd03a84addf546523c0ecd6f6564927227085f803d520e65915ae5aaf0e26dfad23d602f3444451abdb8d3001bc551f30d41e6b35986b307 + checksum: 6dce457e58dcf9dab8bfb945a7cb9507a2fb686c143d04b77f2f1fe1c1247f9fa76134c872203c3e10398005155f4b9bb4b5e43edfb956c1e9ae4d3d95b6ceb3 languageName: node linkType: hard -"@asyncapi/parser@npm:^3.0.0-next-major-spec.10": - version: 3.0.0-next-major-spec.12 - resolution: "@asyncapi/parser@npm:3.0.0-next-major-spec.12" +"@asyncapi/protobuf-schema-parser@npm:^3.0.4": + version: 3.0.4 + resolution: "@asyncapi/protobuf-schema-parser@npm:3.0.4" dependencies: - "@asyncapi/specs": ^6.0.0-next-major-spec.9 - "@openapi-contrib/openapi-schema-to-json-schema": ~3.2.0 - "@stoplight/json-ref-resolver": ^3.1.5 - "@stoplight/spectral-core": ^1.16.1 - "@stoplight/spectral-functions": ^1.7.2 - "@stoplight/spectral-parsers": ^1.0.2 - "@types/json-schema": ^7.0.11 - "@types/urijs": ^1.19.19 - ajv: ^8.11.0 - ajv-errors: ^3.0.0 - ajv-formats: ^2.1.1 - avsc: ^5.7.5 - js-yaml: ^4.1.0 - jsonpath-plus: ^7.2.0 - node-fetch: 2.6.7 - ramldt2jsonschema: ^1.2.3 - webapi-parser: ^0.5.0 - checksum: 960843cc3303fe6c2c2fe227edb66d396fa96100b5e1e7ed001bde70a341505db0e638e5a518f9d00c4daa707c77c4779aa36ea8d7cd264d1e66335587c30750 - languageName: node - linkType: hard - -"@asyncapi/protobuf-schema-parser@npm:3.0.0": - version: 3.0.0 - resolution: "@asyncapi/protobuf-schema-parser@npm:3.0.0" - dependencies: - "@asyncapi/parser": ^2.1.0 + "@asyncapi/parser": ^3.0.1 "@types/protocol-buffers-schema": ^3.4.1 protocol-buffers-schema: ^3.6.0 - checksum: a80bbc9bb5ef4e21d5eb0aa56f5aa1207afff482a72abcbf45faece6f295bdeaf81fff349aa1542ef4cf8674f1ff943e8bc29371b07154e615e097d80b15a7dd + checksum: c176e6d86e53f342ac91067279fb6e1ac3ed9d7f36de197fc723a2ceaf2a2588267c445203d67edcb3cd75308c0c0d6ea401ad69508bfe378c9194420702d3db languageName: node linkType: hard -"@asyncapi/react-component@npm:1.2.2": - version: 1.2.2 - resolution: "@asyncapi/react-component@npm:1.2.2" +"@asyncapi/react-component@npm:1.2.6": + version: 1.2.6 + resolution: "@asyncapi/react-component@npm:1.2.6" dependencies: - "@asyncapi/avro-schema-parser": ^3.0.5 - "@asyncapi/openapi-schema-parser": ^3.0.6 - "@asyncapi/parser": ^3.0.0-next-major-spec.10 - "@asyncapi/protobuf-schema-parser": 3.0.0 + "@asyncapi/avro-schema-parser": ^3.0.7 + "@asyncapi/openapi-schema-parser": ^3.0.8 + "@asyncapi/parser": ^3.0.1 + "@asyncapi/protobuf-schema-parser": ^3.0.4 highlight.js: ^10.7.2 isomorphic-dompurify: ^0.13.0 marked: ^4.0.14 @@ -241,7 +216,7 @@ __metadata: peerDependencies: react: ">=16.8.0" react-dom: ">=16.8.0" - checksum: d8b4d692b6bc1c8a98c2cb61d72207e4faea9c03ce39f959131da43b21cbd4e7efb0e8d137a40eac6bdf3c389bf33ff534efd259f38f580ee7205aa702e803d1 + checksum: 4afb34562767771048d0848323adea8d498dc555cc529947d4a45f3ec8d7f172bb454814bcf9c4419e105a743736368b56b3ed54d09b60addc06a287ca0e82b9 languageName: node linkType: hard @@ -254,21 +229,12 @@ __metadata: languageName: node linkType: hard -"@asyncapi/specs@npm:^5.1.0": - version: 5.1.0 - resolution: "@asyncapi/specs@npm:5.1.0" +"@asyncapi/specs@npm:^6.1.0": + version: 6.1.0 + resolution: "@asyncapi/specs@npm:6.1.0" dependencies: "@types/json-schema": ^7.0.11 - checksum: a4ca804d028c8ecb4d6484de84633854e64ba32fb995caa413cb1388da1e4f2bce3b8c635cd3a9217f6f0c202b566498d09301cd825d6485014a7b510a5d3faf - languageName: node - linkType: hard - -"@asyncapi/specs@npm:^6.0.0-next-major-spec.9": - version: 6.0.0-next-major-spec.13 - resolution: "@asyncapi/specs@npm:6.0.0-next-major-spec.13" - dependencies: - "@types/json-schema": ^7.0.11 - checksum: a66bedba036684fa7984d94d211fe5aaac28043d3a79c4fc6bf5ddabf3a384e1a9cb3b4224d1a937448d2a6e24e3ddf5c4e8c7a32804963994d84fa5e0285b7c + checksum: d4ad199ef58b8ef6be081e2e71fd172fdf6720479f3ae6f9b1e58037f833ca177c8af1dadeab4525c2c07e68ea0a4832e0d3dd67c3b033b988ca2435245f6aa6 languageName: node linkType: hard @@ -4655,7 +4621,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-api-docs@workspace:plugins/api-docs" dependencies: - "@asyncapi/react-component": 1.2.2 + "@asyncapi/react-component": 1.2.6 "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/core-app-api": "workspace:^" @@ -20427,30 +20393,6 @@ __metadata: languageName: node linkType: hard -"ajv@npm:6.5.2": - version: 6.5.2 - resolution: "ajv@npm:6.5.2" - dependencies: - fast-deep-equal: ^2.0.1 - fast-json-stable-stringify: ^2.0.0 - json-schema-traverse: ^0.4.1 - uri-js: ^4.2.1 - checksum: ac8590895952e6387f923cf7e130e2b4fac13e175caa2934c7792e8a54f2a619e805f769d6f1b5d26d75401fccbe69e5b1fe31ebae39f300c5660a78597ee2fb - languageName: node - linkType: hard - -"ajv@npm:^5.0.0": - version: 5.5.2 - resolution: "ajv@npm:5.5.2" - dependencies: - co: ^4.6.0 - fast-deep-equal: ^1.0.0 - fast-json-stable-stringify: ^2.0.0 - json-schema-traverse: ^0.3.0 - checksum: a69645c843e1676b0ae1c5192786e546427f808f386d26127c6585479378066c64341ceec0b127b6789d79628e71d2a732d402f575b98f9262db230d7b715a94 - languageName: node - linkType: hard - "ajv@npm:^6.12.2, ajv@npm:^6.12.4, ajv@npm:^6.12.5, ajv@npm:^6.5.5, ajv@npm:~6.12.6": version: 6.12.6 resolution: "ajv@npm:6.12.6" @@ -23103,7 +23045,7 @@ __metadata: languageName: node linkType: hard -"commander@npm:^5.0.0, commander@npm:^5.1.0": +"commander@npm:^5.1.0": version: 5.1.0 resolution: "commander@npm:5.1.0" checksum: 0b7fec1712fbcc6230fcb161d8d73b4730fa91a21dc089515489402ad78810547683f058e2a9835929c212fead1d6a6ade70db28bbb03edbc2829a9ab7d69447 @@ -27207,20 +27149,6 @@ __metadata: languageName: node linkType: hard -"fast-deep-equal@npm:^1.0.0": - version: 1.1.0 - resolution: "fast-deep-equal@npm:1.1.0" - checksum: 69b4c9534d9805f13a341aa72f69641d0b9ae3cc8beb25c64e68a257241c7bb34370266db27ae4fc3c4da0518448c01a5f587a096a211471c86a38facd9a1486 - languageName: node - linkType: hard - -"fast-deep-equal@npm:^2.0.1": - version: 2.0.1 - resolution: "fast-deep-equal@npm:2.0.1" - checksum: b701835a87985e0ec4925bdf1f0c1e7eb56309b5d12d534d5b4b69d95a54d65bb16861c081781ead55f73f12d6c60ba668713391ee7fbf6b0567026f579b7b0b - languageName: node - linkType: hard - "fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": version: 3.1.3 resolution: "fast-deep-equal@npm:3.1.3" @@ -31639,7 +31567,7 @@ __metadata: languageName: node linkType: hard -"js-yaml@npm:^3.10.0, js-yaml@npm:^3.13.0, js-yaml@npm:^3.13.1, js-yaml@npm:^3.14.0, js-yaml@npm:^3.6.1, js-yaml@npm:^3.8.3": +"js-yaml@npm:^3.10.0, js-yaml@npm:^3.13.0, js-yaml@npm:^3.13.1, js-yaml@npm:^3.6.1, js-yaml@npm:^3.8.3": version: 3.14.1 resolution: "js-yaml@npm:3.14.1" dependencies: @@ -31916,15 +31844,6 @@ __metadata: languageName: node linkType: hard -"json-schema-migrate@npm:^0.2.0": - version: 0.2.0 - resolution: "json-schema-migrate@npm:0.2.0" - dependencies: - ajv: ^5.0.0 - checksum: fc5b3ed2cfc5d02059836120653b63f846a18037ec554b47267f9c104750f8fa3f3acb38d0129f116fd2db017c69cc90456cfae66930aa1d328fe12a422c0125 - languageName: node - linkType: hard - "json-schema-to-ts@npm:^2.6.2": version: 2.9.2 resolution: "json-schema-to-ts@npm:2.9.2" @@ -31936,13 +31855,6 @@ __metadata: languageName: node linkType: hard -"json-schema-traverse@npm:^0.3.0": - version: 0.3.1 - resolution: "json-schema-traverse@npm:0.3.1" - checksum: a685c36222023471c25c86cddcff506306ecb8f8941922fd356008419889c41c38e1c16d661d5499d0a561b34f417693e9bb9212ba2b2b2f8f8a345a49e4ec1a - languageName: node - linkType: hard - "json-schema-traverse@npm:^0.4.1": version: 0.4.1 resolution: "json-schema-traverse@npm:0.4.1" @@ -38291,21 +38203,6 @@ __metadata: languageName: node linkType: hard -"ramldt2jsonschema@npm:^1.2.3": - version: 1.2.3 - resolution: "ramldt2jsonschema@npm:1.2.3" - dependencies: - commander: ^5.0.0 - js-yaml: ^3.14.0 - json-schema-migrate: ^0.2.0 - webapi-parser: ^0.5.0 - bin: - dt2js: bin/dt2js.js - js2dt: bin/js2dt.js - checksum: db6b89f4c088184290ea27448cfd64985e253543209e0b80bfb12b0b9640253b59418b671164af9055143018ef4be010c5f52ca853386636267269208f2f3512 - languageName: node - linkType: hard - "randexp@npm:0.4.6": version: 0.4.6 resolution: "randexp@npm:0.4.6" @@ -43710,7 +43607,7 @@ __metadata: languageName: node linkType: hard -"uri-js@npm:^4.2.1, uri-js@npm:^4.2.2, uri-js@npm:^4.4.1": +"uri-js@npm:^4.2.2, uri-js@npm:^4.4.1": version: 4.4.1 resolution: "uri-js@npm:4.4.1" dependencies: @@ -44440,15 +44337,6 @@ __metadata: languageName: node linkType: hard -"webapi-parser@npm:^0.5.0": - version: 0.5.0 - resolution: "webapi-parser@npm:0.5.0" - dependencies: - ajv: 6.5.2 - checksum: bb9fb534b33939fcb420aa5c564e05595f72b543a84ccb71de642fb5852aa9481d1debcebbf4d7ca9bfd192c3d829848baa8c03e7b2ae81ee69171f012d32a60 - languageName: node - linkType: hard - "webidl-conversions@npm:^3.0.0": version: 3.0.1 resolution: "webidl-conversions@npm:3.0.1" From d2ce05b772601a67b695626b9a27ffed620f21d8 Mon Sep 17 00:00:00 2001 From: Taras Mankovski Date: Mon, 4 Dec 2023 19:54:50 -0500 Subject: [PATCH 068/275] Execute openapi-generator-cli from @backstage/repo-tools directory Signed-off-by: Taras Mankovski --- packages/repo-tools/package.json | 3 ++- packages/repo-tools/src/commands/openapi/client/generate.ts | 6 +----- packages/repo-tools/templates/typescript-backstage.yaml | 2 ++ 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/repo-tools/package.json b/packages/repo-tools/package.json index 991dcbd7af..7a7e56d68c 100644 --- a/packages/repo-tools/package.json +++ b/packages/repo-tools/package.json @@ -87,7 +87,8 @@ "files": [ "bin", "dist/**/*.js", - "templates" + "templates", + "openapitools.json" ], "nodemonConfig": { "watch": "./src", diff --git a/packages/repo-tools/src/commands/openapi/client/generate.ts b/packages/repo-tools/src/commands/openapi/client/generate.ts index 8d85e9cd67..f827f1005f 100644 --- a/packages/repo-tools/src/commands/openapi/client/generate.ts +++ b/packages/repo-tools/src/commands/openapi/client/generate.ts @@ -51,16 +51,12 @@ async function generate(spec: string, outputDirectory: string) { '@backstage/repo-tools', 'templates/typescript-backstage.yaml', ), - '-t', - resolvePackagePath( - '@backstage/repo-tools', - 'templates/typescript-backstage', - ), '--generator-key', 'v3.0', ], { maxBuffer: Number.MAX_VALUE, + cwd: resolvePackagePath('@backstage/repo-tools'), env: { ...process.env, }, diff --git a/packages/repo-tools/templates/typescript-backstage.yaml b/packages/repo-tools/templates/typescript-backstage.yaml index 310a21e75a..cda9a48a76 100644 --- a/packages/repo-tools/templates/typescript-backstage.yaml +++ b/packages/repo-tools/templates/typescript-backstage.yaml @@ -1,3 +1,5 @@ +templateDir: templates/typescript-backstage + files: api.mustache: templateType: API From b3e4e3b60ab69a61128a2281c3df9a4868080d56 Mon Sep 17 00:00:00 2001 From: Taras Mankovski Date: Mon, 4 Dec 2023 19:57:11 -0500 Subject: [PATCH 069/275] Updated changeset Signed-off-by: Taras Mankovski --- .changeset/spotty-terms-occur.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/spotty-terms-occur.md b/.changeset/spotty-terms-occur.md index 923cd04beb..471ba6d0dc 100644 --- a/.changeset/spotty-terms-occur.md +++ b/.changeset/spotty-terms-occur.md @@ -2,4 +2,4 @@ '@backstage/repo-tools': patch --- -No longer using yarn to execute openapi-generator-cli and prettier in `repo-tools openapi generate-client` +Execute `openapi-generator-cli` from `@backstage/repo-tools` directory to force it to use our openapitools.json config file. From 6eb6a618a5fc8bf521145cf2d97b3f06dc85dad8 Mon Sep 17 00:00:00 2001 From: Deepankumar Loganathan Date: Tue, 5 Dec 2023 08:24:13 +0100 Subject: [PATCH 070/275] prettier fixed Signed-off-by: Deepankumar Loganathan --- microsite/data/plugins/azure-storage.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/microsite/data/plugins/azure-storage.yaml b/microsite/data/plugins/azure-storage.yaml index 4d371a77d7..655a6421ed 100644 --- a/microsite/data/plugins/azure-storage.yaml +++ b/microsite/data/plugins/azure-storage.yaml @@ -8,7 +8,7 @@ documentation: https://github.com/deepan10/backstage-plugins/tree/main/plugins/a iconUrl: /img/azure-storage-folder.png npmPackageName: 'backstage-plugin-azure-storage' tags: - - Azure + - Azure - Azure Storage - Infrastructure addedDate: '2023-12-01' From cf5cc4c8a0bdf30fc1c777c348eef0cc514b4563 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Wed, 29 Nov 2023 16:55:12 +0100 Subject: [PATCH 071/275] core-compat-api: recursive collectLecacyRoutes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/nasty-rockets-bathe.md | 5 + packages/core-compat-api/package.json | 25 +-- .../src/collectLegacyRoutes.test.tsx | 144 ++++++++++++++- .../src/collectLegacyRoutes.tsx | 173 ++++++++++++++---- .../src/convertLegacyApp.test.tsx | 2 +- .../src/convertLegacyRouteRef.ts | 15 +- yarn.lock | 1 + 7 files changed, 310 insertions(+), 55 deletions(-) create mode 100644 .changeset/nasty-rockets-bathe.md diff --git a/.changeset/nasty-rockets-bathe.md b/.changeset/nasty-rockets-bathe.md new file mode 100644 index 0000000000..1320b000b7 --- /dev/null +++ b/.changeset/nasty-rockets-bathe.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-compat-api': minor +--- + +Discover plugins and routes recursively beneath the root routes in `collectLecacyRoutes` diff --git a/packages/core-compat-api/package.json b/packages/core-compat-api/package.json index f713b49cf6..dd602f5380 100644 --- a/packages/core-compat-api/package.json +++ b/packages/core-compat-api/package.json @@ -22,9 +22,21 @@ "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack" }, + "dependencies": { + "@backstage/core-app-api": "workspace:^", + "@backstage/core-plugin-api": "workspace:^", + "@backstage/frontend-plugin-api": "workspace:^", + "@backstage/version-bridge": "workspace:^", + "@types/react": "^16.13.1 || ^17.0.0" + }, + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/frontend-test-utils": "workspace:^", + "@backstage/plugin-catalog": "workspace:^", "@backstage/plugin-puppetdb": "workspace:^", "@backstage/plugin-stackstorm": "workspace:^", "@oriflame/backstage-plugin-score-card": "^0.7.0", @@ -33,16 +45,5 @@ }, "files": [ "dist" - ], - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, - "dependencies": { - "@backstage/core-app-api": "workspace:^", - "@backstage/core-plugin-api": "workspace:^", - "@backstage/frontend-plugin-api": "workspace:^", - "@backstage/version-bridge": "workspace:^", - "@types/react": "^16.13.1 || ^17.0.0" - } + ] } diff --git a/packages/core-compat-api/src/collectLegacyRoutes.test.tsx b/packages/core-compat-api/src/collectLegacyRoutes.test.tsx index 3dd9f330cc..862ef68bb5 100644 --- a/packages/core-compat-api/src/collectLegacyRoutes.test.tsx +++ b/packages/core-compat-api/src/collectLegacyRoutes.test.tsx @@ -15,11 +15,19 @@ */ import { FlatRoutes } from '@backstage/core-app-api'; +import { + CatalogEntityPage, + CatalogIndexPage, + EntityAboutCard, + EntityLayout, + EntitySwitch, + isKind, +} from '@backstage/plugin-catalog'; import { PuppetDbPage } from '@backstage/plugin-puppetdb'; import { StackstormPage } from '@backstage/plugin-stackstorm'; import { ScoreBoardPage } from '@oriflame/backstage-plugin-score-card'; -import React from 'react'; -import { Route } from 'react-router-dom'; +import React, { Fragment } from 'react'; +import { Route, Routes } from 'react-router-dom'; import { collectLegacyRoutes } from './collectLegacyRoutes'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports @@ -89,7 +97,7 @@ describe('collectLegacyRoutes', () => { defaultConfig: { path: 'puppetdb' }, }, { - id: 'page:puppetDb/2', + id: 'page:puppetDb/1', attachTo: { id: 'core/routes', input: 'routes' }, disabled: false, defaultConfig: { path: 'puppetdb' }, @@ -103,4 +111,134 @@ describe('collectLegacyRoutes', () => { }, ]); }); + + it('supports recursion into children, including passing through fragments', () => { + const collected = collectLegacyRoutes( + + } /> + } + > + + + + + } + /> + + + + + + + + + + + + + + + + , + ); + + expect( + collected.map(p => ({ + id: p.id, + extensions: toInternalBackstagePlugin(p).extensions.map(e => ({ + id: e.id, + attachTo: e.attachTo, + disabled: e.disabled, + defaultConfig: e.configSchema?.parse({}), + })), + })), + ).toEqual([ + { + id: 'catalog', + extensions: [ + { + id: 'page:catalog', + attachTo: { id: 'core/routes', input: 'routes' }, + disabled: false, + defaultConfig: { path: 'catalog' }, + }, + { + id: 'page:catalog/1', + attachTo: { id: 'core/routes', input: 'routes' }, + defaultConfig: { path: 'catalog/:namespace/:kind/:name' }, + disabled: false, + }, + { + id: 'routing-shim:catalog/2', + attachTo: { + id: 'page:catalog/1', + input: 'childRoutingShims', + }, + defaultConfig: undefined, + disabled: false, + }, + { + id: 'routing-shim:catalog/3', + attachTo: { + id: 'routing-shim:catalog/2', + input: 'childRoutingShims', + }, + defaultConfig: undefined, + disabled: false, + }, + { + id: 'routing-shim:catalog/4', + attachTo: { + id: 'routing-shim:catalog/3', + input: 'childRoutingShims', + }, + defaultConfig: undefined, + disabled: false, + }, + { + id: 'api:plugin.catalog.service', + attachTo: { + id: 'core', + input: 'apis', + }, + defaultConfig: undefined, + disabled: false, + }, + { + id: 'api:catalog-react.starred-entities', + attachTo: { + id: 'core', + input: 'apis', + }, + defaultConfig: undefined, + disabled: false, + }, + { + id: 'api:plugin.catalog.entity-presentation', + attachTo: { + id: 'core', + input: 'apis', + }, + defaultConfig: undefined, + disabled: false, + }, + ], + }, + { + id: 'score-card', + extensions: [ + { + id: 'api:plugin.scoringdata.service', + attachTo: { id: 'core', input: 'apis' }, + disabled: false, + }, + ], + }, + ]); + }); }); diff --git a/packages/core-compat-api/src/collectLegacyRoutes.tsx b/packages/core-compat-api/src/collectLegacyRoutes.tsx index 92bced29a2..729ead2786 100644 --- a/packages/core-compat-api/src/collectLegacyRoutes.tsx +++ b/packages/core-compat-api/src/collectLegacyRoutes.tsx @@ -14,20 +14,24 @@ * limitations under the License. */ -import React, { ReactNode } from 'react'; -import { - createApiExtension, - createPageExtension, - createPlugin, - BackstagePlugin, - ExtensionDefinition, -} from '@backstage/frontend-plugin-api'; -import { Route, Routes } from 'react-router-dom'; import { + AnyRouteRefParams, BackstagePlugin as LegacyBackstagePlugin, RouteRef, getComponentData, } from '@backstage/core-plugin-api'; +import { + BackstagePlugin, + ExtensionDefinition, + coreExtensionData, + createApiExtension, + createExtension, + createExtensionInput, + createPageExtension, + createPlugin, +} from '@backstage/frontend-plugin-api'; +import React, { Children, ReactNode, isValidElement } from 'react'; +import { Route, Routes } from 'react-router-dom'; import { convertLegacyRouteRef } from './convertLegacyRouteRef'; /* @@ -58,58 +62,150 @@ Existing tasks: */ +// Creates a shim extension whose purpose is to build up the tree (anchored at +// the root page) of paths/routeRefs so that the app can bind them properly. +function makeRoutingShimExtension(options: { + name: string; + parentExtensionId: string; + routePath?: string; + routeRef?: RouteRef; +}) { + const { name, parentExtensionId, routePath, routeRef } = options; + return createExtension({ + kind: 'routing-shim', + name, + attachTo: { id: parentExtensionId, input: 'childRoutingShims' }, + inputs: { + childRoutingShims: createExtensionInput({ + routePath: coreExtensionData.routePath.optional(), + routeRef: coreExtensionData.routeRef.optional(), + }), + }, + output: { + routePath: coreExtensionData.routePath.optional(), + routeRef: coreExtensionData.routeRef.optional(), + }, + factory: () => ({ + routePath, + routeRef: routeRef ? convertLegacyRouteRef(routeRef) : undefined, + }), + }); +} + +function visitRouteChildren(options: { + children: ReactNode; + parentExtensionId: string; + context: { + pluginId: string; + extensions: ExtensionDefinition[]; + getUniqueName: () => string; + discoverPlugin: (plugin: LegacyBackstagePlugin) => void; + }; +}): void { + const { children, parentExtensionId, context } = options; + const { pluginId, extensions, getUniqueName, discoverPlugin } = context; + + Children.forEach(children, node => { + if (!isValidElement(node)) { + return; + } + + const plugin = getComponentData(node, 'core.plugin'); + const routeRef = getComponentData>( + node, + 'core.mountPoint', + ); + const routePath: string | undefined = node.props?.path; + + if (plugin) { + // We just mark the plugin as discovered, but don't change the context + discoverPlugin(plugin); + } + + let nextParentExtensionId = parentExtensionId; + if (routeRef || routePath) { + const nextParentExtensionName = getUniqueName(); + nextParentExtensionId = `routing-shim:${pluginId}/${nextParentExtensionName}`; + extensions.push( + makeRoutingShimExtension({ + name: nextParentExtensionName, + parentExtensionId, + routePath, + routeRef, + }), + ); + } + + visitRouteChildren({ + children: node.props.children, + parentExtensionId: nextParentExtensionId, + context, + }); + }); +} + /** @public */ export function collectLegacyRoutes( flatRoutesElement: JSX.Element, ): BackstagePlugin[] { - const createdPluginIds = new Map< + const pluginExtensions = new Map< LegacyBackstagePlugin, ExtensionDefinition[] >(); + const getUniqueName = (() => { + let currentIndex = 1; + return () => String(currentIndex++); + })(); + + const getPluginExtensions = (plugin: LegacyBackstagePlugin) => { + let extensions = pluginExtensions.get(plugin); + if (!extensions) { + extensions = []; + pluginExtensions.set(plugin, extensions); + } + return extensions; + }; + React.Children.forEach( flatRoutesElement.props.children, (route: ReactNode) => { - if (!React.isValidElement(route)) { - return; - } - // TODO(freben): Handle feature flag and permissions framework wrapper elements - if (route.type !== Route) { + if (!React.isValidElement(route) || route.type !== Route) { return; } const routeElement = route.props.element; - - // TODO: to support deeper extension component, e.g. hidden within , use https://github.com/backstage/backstage/blob/518a34646b79ec2028cc0ed6bc67d4366c51c4d6/packages/core-app-api/src/routing/collectors.tsx#L69 + const path: string | undefined = route.props.path; const plugin = getComponentData( routeElement, 'core.plugin', ); - if (!plugin) { - return; - } - const routeRef = getComponentData( routeElement, 'core.mountPoint', ); + if (!plugin || !path) { + return; + } - const detectedExtensions = - createdPluginIds.get(plugin) ?? - new Array>(); - createdPluginIds.set(plugin, detectedExtensions); + const extensions = getPluginExtensions(plugin); + const pageExtensionName = extensions.length ? getUniqueName() : undefined; + const pageExtensionId = `page:${plugin.getId()}${ + pageExtensionName ? `/${pageExtensionName}` : pageExtensionName + }`; - const path: string = route.props.path; - - detectedExtensions.push( + extensions.push( createPageExtension({ - name: detectedExtensions.length - ? String(detectedExtensions.length + 1) - : undefined, + name: pageExtensionName, defaultPath: path[0] === '/' ? path.slice(1) : path, routeRef: routeRef ? convertLegacyRouteRef(routeRef) : undefined, - + inputs: { + childRoutingShims: createExtensionInput({ + routePath: coreExtensionData.routePath.optional(), + routeRef: coreExtensionData.routeRef.optional(), + }), + }, loader: async () => route.props.children ? ( @@ -122,10 +218,21 @@ export function collectLegacyRoutes( ), }), ); + + visitRouteChildren({ + children: route.props.children, + parentExtensionId: pageExtensionId, + context: { + pluginId: plugin.getId(), + extensions, + getUniqueName, + discoverPlugin: getPluginExtensions, + }, + }); }, ); - return Array.from(createdPluginIds).map(([plugin, extensions]) => + return Array.from(pluginExtensions).map(([plugin, extensions]) => createPlugin({ id: plugin.getId(), extensions: [ diff --git a/packages/core-compat-api/src/convertLegacyApp.test.tsx b/packages/core-compat-api/src/convertLegacyApp.test.tsx index 4a5be57bc8..9fae0128b0 100644 --- a/packages/core-compat-api/src/convertLegacyApp.test.tsx +++ b/packages/core-compat-api/src/convertLegacyApp.test.tsx @@ -97,7 +97,7 @@ describe('convertLegacyApp', () => { defaultConfig: { path: 'puppetdb' }, }, { - id: 'page:puppetDb/2', + id: 'page:puppetDb/1', attachTo: { id: 'core/routes', input: 'routes' }, disabled: false, defaultConfig: { path: 'puppetdb' }, diff --git a/packages/core-compat-api/src/convertLegacyRouteRef.ts b/packages/core-compat-api/src/convertLegacyRouteRef.ts index 2495f3719c..c5ee603722 100644 --- a/packages/core-compat-api/src/convertLegacyRouteRef.ts +++ b/packages/core-compat-api/src/convertLegacyRouteRef.ts @@ -91,6 +91,7 @@ export function convertLegacyRouteRef( if (type === 'absolute') { const legacyRef = ref as LegacyRouteRef; + const legacyRefStr = String(legacyRef); const newRef = toInternalRouteRef( createRouteRef<{ [key in string]: string }>({ params: legacyRef.params as string[], @@ -104,18 +105,19 @@ export function convertLegacyRouteRef( return newRef.getParams(); }, getDescription() { - return newRef.getDescription(); + return legacyRefStr; }, setId(id: string) { newRef.setId(id); }, toString() { - return newRef.toString(); + return legacyRefStr; }, }); } if (type === 'sub') { const legacyRef = ref as LegacySubRouteRef; + const legacyRefStr = String(legacyRef); const newRef = toInternalSubRouteRef( createSubRouteRef({ path: legacyRef.path, @@ -133,15 +135,16 @@ export function convertLegacyRouteRef( return newRef.getParent(); }, getDescription() { - return newRef.getDescription(); + return legacyRefStr; }, toString() { - return newRef.toString(); + return legacyRefStr; }, }); } if (type === 'external') { const legacyRef = ref as LegacyExternalRouteRef; + const legacyRefStr = String(legacyRef); const newRef = toInternalExternalRouteRef( createExternalRouteRef<{ [key in string]: string }>({ params: legacyRef.params as string[], @@ -157,13 +160,13 @@ export function convertLegacyRouteRef( return newRef.getParams(); }, getDescription() { - return newRef.getDescription(); + return legacyRefStr; }, setId(id: string) { newRef.setId(id); }, toString() { - return newRef.toString(); + return legacyRefStr; }, }); } diff --git a/yarn.lock b/yarn.lock index f38145a560..1f22be1c74 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3856,6 +3856,7 @@ __metadata: "@backstage/core-plugin-api": "workspace:^" "@backstage/frontend-plugin-api": "workspace:^" "@backstage/frontend-test-utils": "workspace:^" + "@backstage/plugin-catalog": "workspace:^" "@backstage/plugin-puppetdb": "workspace:^" "@backstage/plugin-stackstorm": "workspace:^" "@backstage/version-bridge": "workspace:^" From cb4197aadb37c8a527ec06358df2e714a6194ac2 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Mon, 4 Dec 2023 23:20:12 +0100 Subject: [PATCH 072/275] refactor: return node in resolved extension inputs Signed-off-by: Camila Belo --- .changeset/slow-bottles-cross.md | 6 ++++ .../src/tree/instantiateAppNodeTree.test.ts | 28 +++++++++++-------- .../src/tree/instantiateAppNodeTree.ts | 25 ++++++++--------- packages/frontend-plugin-api/api-report.md | 2 +- .../src/wiring/createExtension.ts | 2 +- 5 files changed, 36 insertions(+), 27 deletions(-) create mode 100644 .changeset/slow-bottles-cross.md diff --git a/.changeset/slow-bottles-cross.md b/.changeset/slow-bottles-cross.md new file mode 100644 index 0000000000..32446f1554 --- /dev/null +++ b/.changeset/slow-bottles-cross.md @@ -0,0 +1,6 @@ +--- +'@backstage/frontend-plugin-api': patch +'@backstage/frontend-app-api': patch +--- + +Forward ` node`` instead of `extensionId` to resolved extension inputs. diff --git a/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts b/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts index 0be4f0a0c4..49f6203ce4 100644 --- a/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts +++ b/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts @@ -26,7 +26,7 @@ import { createAppNodeInstance, instantiateAppNodeTree, } from './instantiateAppNodeTree'; -import { AppNodeInstance, AppNodeSpec } from '@backstage/frontend-plugin-api'; +import { AppNodeSpec } from '@backstage/frontend-plugin-api'; import { resolveAppTree } from './resolveAppTree'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports import { resolveExtensionDefinition } from '../../../frontend-plugin-api/src/wiring/resolveExtensionDefinition'; @@ -85,11 +85,12 @@ function makeNode( function makeInstanceWithId( extension: Extension, config?: TConfig, -): { id: string; instance: AppNodeInstance } { +): AppNode { + const node = makeNode(extension, { config }); return { - id: extension.id, + ...node, instance: createAppNodeInstance({ - node: makeNode(extension, { config }), + node, attachments: new Map(), }), }; @@ -152,8 +153,10 @@ describe('instantiateAppNodeTree', () => { instantiateAppNodeTree(tree.root); expect(tree.root.instance).toBeDefined(); expect(childNode?.instance).toBeDefined(); - expect(tree.root.instance?.getData(inputMirrorDataRef)).toEqual({ - test: [{ extensionId: 'child-node', output: { test: 'test' } }], + expect(tree.root.instance?.getData(inputMirrorDataRef)).toMatchObject({ + test: [ + { node: { spec: { id: 'child-node' } }, output: { test: 'test' } }, + ], }); // Multiple calls should have no effect @@ -295,18 +298,21 @@ describe('createAppNodeInstance', () => { }); expect(Array.from(instance.getDataRefs())).toEqual([inputMirrorDataRef]); - expect(instance.getData(inputMirrorDataRef)).toEqual({ + expect(instance.getData(inputMirrorDataRef)).toMatchObject({ optionalSingletonPresent: { - extensionId: 'core/test', + node: { spec: { id: 'core/test' } }, output: { test: 'optionalSingletonPresent' }, }, singleton: { - extensionId: 'core/test', + node: { spec: { id: 'core/test' } }, output: { test: 'singleton', other: 2 }, }, many: [ - { extensionId: 'core/test', output: { test: 'many1' } }, - { extensionId: 'core/test', output: { test: 'many2', other: 3 } }, + { node: { spec: { id: 'core/test' } }, output: { test: 'many1' } }, + { + node: { spec: { id: 'core/test' } }, + output: { test: 'many2', other: 3 }, + }, ], }); }); diff --git a/packages/frontend-app-api/src/tree/instantiateAppNodeTree.ts b/packages/frontend-app-api/src/tree/instantiateAppNodeTree.ts index ca51f10921..dee1c83e3f 100644 --- a/packages/frontend-app-api/src/tree/instantiateAppNodeTree.ts +++ b/packages/frontend-app-api/src/tree/instantiateAppNodeTree.ts @@ -29,14 +29,14 @@ type Mutable = { function resolveInputData( dataMap: AnyExtensionDataMap, - attachment: { id: string; instance: AppNodeInstance }, + attachment: AppNode, inputName: string, ) { return mapValues(dataMap, ref => { - const value = attachment.instance.getData(ref); + const value = attachment.instance?.getData(ref); if (value === undefined && !ref.config.optional) { throw new Error( - `input '${inputName}' did not receive required extension data '${ref.id}' from extension '${attachment.id}'`, + `input '${inputName}' did not receive required extension data '${ref.id}' from extension '${attachment.spec.id}'`, ); } return value; @@ -45,7 +45,7 @@ function resolveInputData( function resolveInputs( inputMap: AnyExtensionInputMap, - attachments: ReadonlyMap, + attachments: ReadonlyMap, ): ResolvedExtensionInputs { const undeclaredAttachments = Array.from(attachments.entries()).filter( ([inputName]) => inputMap[inputName] === undefined, @@ -59,7 +59,7 @@ function resolveInputs( .map( ([k, exts]) => `'${k}' from extension${exts.length > 1 ? 's' : ''} '${exts - .map(e => e.id) + .map(e => e.spec.id) .join("', '")}'`, ) .join(' and ')}`, @@ -71,7 +71,7 @@ function resolveInputs( if (input.config.singleton) { if (attachedNodes.length > 1) { - const attachedNodeIds = attachedNodes.map(e => e.id); + const attachedNodeIds = attachedNodes.map(e => e.spec.id); throw Error( `expected ${ input.config.optional ? 'at most' : 'exactly' @@ -86,7 +86,7 @@ function resolveInputs( throw Error(`input '${inputName}' is required but was not received`); } return { - extensionId: attachedNodes[0].id, + node: attachedNodes[0], output: resolveInputData( input.extensionData, attachedNodes[0], @@ -96,7 +96,7 @@ function resolveInputs( } return attachedNodes.map(attachment => ({ - extensionId: attachment.id, + node: attachment, output: resolveInputData(input.extensionData, attachment, inputName), })); }) as ResolvedExtensionInputs; @@ -105,7 +105,7 @@ function resolveInputs( /** @internal */ export function createAppNodeInstance(options: { node: AppNode; - attachments: ReadonlyMap; + attachments: ReadonlyMap; }): AppNodeInstance { const { node, attachments } = options; const { id, extension, config } = node.spec; @@ -172,10 +172,7 @@ export function instantiateAppNodeTree(rootNode: AppNode): void { return undefined; } - const instantiatedAttachments = new Map< - string, - { id: string; instance: AppNodeInstance }[] - >(); + const instantiatedAttachments = new Map(); for (const [input, children] of node.edges.attachments) { const instantiatedChildren = children.flatMap(child => { @@ -183,7 +180,7 @@ export function instantiateAppNodeTree(rootNode: AppNode): void { if (!childInstance) { return []; } - return [{ id: child.spec.id, instance: childInstance }]; + return [child]; }); if (instantiatedChildren.length > 0) { instantiatedAttachments.set(input, instantiatedChildren); diff --git a/packages/frontend-plugin-api/api-report.md b/packages/frontend-plugin-api/api-report.md index e8f4f16e97..9435a239cb 100644 --- a/packages/frontend-plugin-api/api-report.md +++ b/packages/frontend-plugin-api/api-report.md @@ -888,7 +888,7 @@ export { ProfileInfoApi }; // @public export type ResolvedExtensionInput = { - extensionId: string; + node: AppNode; output: ExtensionDataValues; }; diff --git a/packages/frontend-plugin-api/src/wiring/createExtension.ts b/packages/frontend-plugin-api/src/wiring/createExtension.ts index cac2ac7b49..ccb93f44ea 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtension.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtension.ts @@ -57,7 +57,7 @@ export type ExtensionDataValues = { */ export type ResolvedExtensionInput = { - extensionId: string; + node: AppNode; output: ExtensionDataValues; }; From 4a77267dacc59d92b14f07fc8cccc8a75bdb4d67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Tue, 5 Dec 2023 11:38:04 +0100 Subject: [PATCH 073/275] address comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .../src/commands/api-reports/api-extractor.ts | 43 +++++++++++-------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/packages/repo-tools/src/commands/api-reports/api-extractor.ts b/packages/repo-tools/src/commands/api-reports/api-extractor.ts index 8f7a298764..b8c241bb0b 100644 --- a/packages/repo-tools/src/commands/api-reports/api-extractor.ts +++ b/packages/repo-tools/src/commands/api-reports/api-extractor.ts @@ -379,17 +379,21 @@ export async function runApiExtraction({ ); const names = group.map(ep => ep.name); - const staleReportFiles = fs.readdirSync(projectFolder).filter(filename => { - const match = - filename.match(/^(.+)-api-report\.md$/) || - filename.match(/^api-report-(.+)\.md$/); - return match && !names.includes(match[1]); - }); + const remainingReportFiles = new Set( + fs + .readdirSync(projectFolder) + .filter( + filename => + filename.match(/^(.+)-api-report\.md$/) || + filename.match(/^api-report(-.+)?\.md$/), + ), + ); for (const name of names) { const suffix = name === 'index' ? '' : `-${name}`; const reportFileName = `api-report${suffix}.md`; const reportPath = resolvePath(projectFolder, reportFileName); + remainingReportFiles.delete(reportFileName); const warningCountBefore = await countApiReportWarnings(reportPath); @@ -593,20 +597,21 @@ export async function runApiExtraction({ 'Please fix these warnings in order to keep the API Reports tidy.', ); } - if (staleReportFiles.length) { - if (noBail) { - for (const f of staleReportFiles) { - fs.rmSync(resolvePath(projectFolder, f)); - console.log(`Deleted deprecated API report ${f}`); - } - } else { - const staleList = staleReportFiles - .map(f => join(packageDir, f)) - .join(', '); - throw new Error( - `The API Report(s) ${staleList} are no longer relevant and should be deleted`, - ); + } + + if (remainingReportFiles.size > 0) { + if (isLocalBuild) { + for (const f of remainingReportFiles) { + fs.rmSync(resolvePath(projectFolder, f)); + console.log(`Deleted deprecated API report ${f}`); } + } else { + const staleList = [...remainingReportFiles] + .map(f => join(packageDir, f)) + .join(', '); + throw new Error( + `The API Report(s) ${staleList} are no longer relevant and should be deleted`, + ); } } } From eb4f52723bdd3613bffc777fbb210ab37c831e50 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Tue, 5 Dec 2023 11:48:31 +0100 Subject: [PATCH 074/275] refactor: rename extension error boundary fallback prop Signed-off-by: Camila Belo --- packages/frontend-plugin-api/src/components/ErrorBoundary.tsx | 4 ++-- .../frontend-plugin-api/src/components/ExtensionBoundary.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/frontend-plugin-api/src/components/ErrorBoundary.tsx b/packages/frontend-plugin-api/src/components/ErrorBoundary.tsx index be988dc14f..6b457fadc9 100644 --- a/packages/frontend-plugin-api/src/components/ErrorBoundary.tsx +++ b/packages/frontend-plugin-api/src/components/ErrorBoundary.tsx @@ -20,7 +20,7 @@ import { CoreErrorBoundaryFallbackProps } from '../types'; type ErrorBoundaryProps = PropsWithChildren<{ plugin?: BackstagePlugin; - fallback: ComponentType; + Fallback: ComponentType; }>; type ErrorBoundaryState = { error?: Error }; @@ -41,7 +41,7 @@ export class ErrorBoundary extends Component< render() { const { error } = this.state; - const { plugin, children, fallback: Fallback } = this.props; + const { plugin, children, Fallback } = this.props; if (error) { return ( diff --git a/packages/frontend-plugin-api/src/components/ExtensionBoundary.tsx b/packages/frontend-plugin-api/src/components/ExtensionBoundary.tsx index db5c911cef..d9bd41f2a9 100644 --- a/packages/frontend-plugin-api/src/components/ExtensionBoundary.tsx +++ b/packages/frontend-plugin-api/src/components/ExtensionBoundary.tsx @@ -70,7 +70,7 @@ export function ExtensionBoundary(props: ExtensionBoundaryProps) { return ( }> - + {children} From 892ea99a5408db88ee3ba9d73b6332b118718be9 Mon Sep 17 00:00:00 2001 From: tejashwikalptaru Date: Mon, 20 Nov 2023 15:36:16 +0530 Subject: [PATCH 075/275] updated AWSS3UrlReader to support CN domain Signed-off-by: tejashwikalptaru --- .../src/reading/AwsS3UrlReader.test.ts | 33 +++++++++++++++++++ .../src/reading/AwsS3UrlReader.ts | 4 +-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/packages/backend-common/src/reading/AwsS3UrlReader.test.ts b/packages/backend-common/src/reading/AwsS3UrlReader.test.ts index b37a052c1d..e3247f190b 100644 --- a/packages/backend-common/src/reading/AwsS3UrlReader.test.ts +++ b/packages/backend-common/src/reading/AwsS3UrlReader.test.ts @@ -53,6 +53,39 @@ describe('parseUrl', () => { bucket: 'my.bucket-3', region: 'us-east-1', }); + expect( + parseUrl('https://s3.amazonaws.com.cn/my.bucket-3/a/puppy.jpg', { + host: 'amazonaws.com', + }), + ).toEqual({ + path: 'a/puppy.jpg', + bucket: 'my.bucket-3', + region: 'us-east-1', + }); + expect( + parseUrl( + 'https://ec-backstage-staging.s3.cn-north-1.amazonaws.com.cn/payments-prod-oas30.json', + { + host: 'amazonaws.com', + }, + ), + ).toEqual({ + path: 'payments-prod-oas30.json', + bucket: 'ec-backstage-staging', + region: 'cn-north-1', + }); + expect( + parseUrl( + 'https://ec-backstage-staging.s3.cn-north-1.amazonaws.com.cn/payments-prod-oas30.json', + { + host: 'amazonaws.com.cn', + }, + ), + ).toEqual({ + path: 'payments-prod-oas30.json', + bucket: 'ec-backstage-staging', + region: 'cn-north-1', + }); expect( parseUrl('https://s3.us-west-2.amazonaws.com/my.bucket-3/a/puppy.jpg', { host: 'amazonaws.com', diff --git a/packages/backend-common/src/reading/AwsS3UrlReader.ts b/packages/backend-common/src/reading/AwsS3UrlReader.ts index 4d4c28071f..23ef0f7b27 100644 --- a/packages/backend-common/src/reading/AwsS3UrlReader.ts +++ b/packages/backend-common/src/reading/AwsS3UrlReader.ts @@ -69,9 +69,9 @@ export function parseUrl( const host = parsedUrl.host; // Treat Amazon hosted separately because it has special region logic - if (config.host === 'amazonaws.com') { + if (config.host === 'amazonaws.com' || config.host === 'amazonaws.com.cn') { const match = host.match( - /^(?:([a-z0-9.-]+)\.)?s3(?:[.-]([a-z0-9-]+))?\.amazonaws\.com$/, + /^(?:([a-z0-9.-]+)\.)?s3(?:[.-]([a-z0-9-]+))?\.amazonaws\.com(\.cn)?$/, ); if (!match) { throw new Error(`Invalid AWS S3 URL ${url}`); From d86a0075b7e27802e6b7b6c07a64364c61ae48c7 Mon Sep 17 00:00:00 2001 From: tejashwikalptaru Date: Tue, 5 Dec 2023 16:43:48 +0530 Subject: [PATCH 076/275] added changeset Signed-off-by: tejashwikalptaru --- .changeset/ninety-suns-accept.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/ninety-suns-accept.md diff --git a/.changeset/ninety-suns-accept.md b/.changeset/ninety-suns-accept.md new file mode 100644 index 0000000000..1ee7b98987 --- /dev/null +++ b/.changeset/ninety-suns-accept.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-common': patch +--- + +Fixed the AwsS3UrlReader host regex and host to allow the S3 reading for CN AWS domain From 32018ffce1c121943897aec2ab307e775decd927 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Tue, 5 Dec 2023 14:24:38 +0100 Subject: [PATCH 077/275] fix the tsx loader bug on node 18.19 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/clean-clouds-fry.md | 5 +++++ packages/cli/package.json | 2 +- .../lib/experimental/startBackendExperimental.ts | 4 +++- yarn.lock | 13 ++++++------- 4 files changed, 15 insertions(+), 9 deletions(-) create mode 100644 .changeset/clean-clouds-fry.md diff --git a/.changeset/clean-clouds-fry.md b/.changeset/clean-clouds-fry.md new file mode 100644 index 0000000000..77b1c97131 --- /dev/null +++ b/.changeset/clean-clouds-fry.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Enable the `tsx` loader to work on Node 18.19 and up diff --git a/packages/cli/package.json b/packages/cli/package.json index 7281d81f0b..e16dfa81a3 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -130,7 +130,7 @@ "swc-loader": "^0.2.3", "tar": "^6.1.12", "terser-webpack-plugin": "^5.1.3", - "tsx": "^3.14.0", + "tsx": "^4.0.0", "util": "^0.12.3", "webpack": "^5.70.0", "webpack-dev-server": "^4.7.3", diff --git a/packages/cli/src/lib/experimental/startBackendExperimental.ts b/packages/cli/src/lib/experimental/startBackendExperimental.ts index 6238b2277b..0ca3b182b5 100644 --- a/packages/cli/src/lib/experimental/startBackendExperimental.ts +++ b/packages/cli/src/lib/experimental/startBackendExperimental.ts @@ -29,7 +29,9 @@ import spawn from 'cross-spawn'; const [nodeMajor, nodeMinor] = process.versions.node.split('.').map(Number); const supportsModuleLoaderRegister = - nodeMajor > 20 || (nodeMajor === 20 && nodeMinor >= 6); + nodeMajor > 20 || + (nodeMajor === 20 && nodeMinor >= 6) || + (nodeMajor === 18 && nodeMinor >= 19); const loaderArgs = [ '--require', diff --git a/yarn.lock b/yarn.lock index 08bd1f270c..9c724386dc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3723,7 +3723,7 @@ __metadata: tar: ^6.1.12 terser-webpack-plugin: ^5.1.3 ts-node: ^10.0.0 - tsx: ^3.14.0 + tsx: ^4.0.0 util: ^0.12.3 webpack: ^5.70.0 webpack-dev-server: ^4.7.3 @@ -41129,7 +41129,7 @@ __metadata: languageName: node linkType: hard -"source-map-support@npm:^0.5.16, source-map-support@npm:^0.5.21, source-map-support@npm:~0.5.20": +"source-map-support@npm:^0.5.16, source-map-support@npm:~0.5.20": version: 0.5.21 resolution: "source-map-support@npm:0.5.21" dependencies: @@ -42982,20 +42982,19 @@ __metadata: languageName: node linkType: hard -"tsx@npm:^3.14.0": - version: 3.14.0 - resolution: "tsx@npm:3.14.0" +"tsx@npm:^4.0.0": + version: 4.6.2 + resolution: "tsx@npm:4.6.2" dependencies: esbuild: ~0.18.20 fsevents: ~2.3.3 get-tsconfig: ^4.7.2 - source-map-support: ^0.5.21 dependenciesMeta: fsevents: optional: true bin: tsx: dist/cli.mjs - checksum: afcef5d9b90b5800cf1ffb749e943f63042d78a4c0d9eef6e13e43f4ecab465d45e2c9812a2c515cbdc2ee913ff1cd01bf5c606a48013dd3ce2214a631b45557 + checksum: a9f13bdb67bfb316bbfc92303d8464323ab1b673aa93ea97271c211a8ba7c59274d4b32eeec5ad8fbd0b04260a092a3ad2116abeb6913254ba456010ff685743 languageName: node linkType: hard From a7f57602d1043e6bec28b832b62e14e7dcd2eb73 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 5 Dec 2023 13:55:44 +0000 Subject: [PATCH 078/275] Version Packages (next) --- .changeset/pre.json | 50 +- docs/releases/v1.21.0-next.3-changelog.md | 3025 +++++++++++++++++ package.json | 2 +- packages/app-defaults/CHANGELOG.md | 11 + packages/app-defaults/package.json | 2 +- packages/app-next-example-plugin/CHANGELOG.md | 8 + packages/app-next-example-plugin/package.json | 2 +- packages/app-next/CHANGELOG.md | 76 + packages/app-next/package.json | 2 +- packages/app/CHANGELOG.md | 76 + packages/app/package.json | 2 +- packages/backend-app-api/CHANGELOG.md | 17 + packages/backend-app-api/package.json | 2 +- packages/backend-common/CHANGELOG.md | 18 + packages/backend-common/package.json | 2 +- packages/backend-defaults/CHANGELOG.md | 9 + packages/backend-defaults/package.json | 2 +- packages/backend-next/CHANGELOG.md | 41 + packages/backend-next/package.json | 2 +- packages/backend-openapi-utils/CHANGELOG.md | 9 + packages/backend-openapi-utils/package.json | 2 +- packages/backend-plugin-api/CHANGELOG.md | 11 + packages/backend-plugin-api/package.json | 2 +- packages/backend-plugin-manager/CHANGELOG.md | 23 + packages/backend-plugin-manager/package.json | 2 +- packages/backend-tasks/CHANGELOG.md | 10 + packages/backend-tasks/package.json | 2 +- packages/backend-test-utils/CHANGELOG.md | 14 + packages/backend-test-utils/package.json | 2 +- packages/backend/CHANGELOG.md | 58 + packages/backend/package.json | 2 +- packages/catalog-client/CHANGELOG.md | 9 + packages/catalog-client/package.json | 2 +- packages/cli/CHANGELOG.md | 21 + packages/cli/package.json | 2 +- packages/config-loader/CHANGELOG.md | 14 + packages/config-loader/package.json | 2 +- packages/core-compat-api/CHANGELOG.md | 18 + packages/core-compat-api/package.json | 2 +- packages/core-components/CHANGELOG.md | 11 + packages/core-components/package.json | 2 +- packages/create-app/CHANGELOG.md | 8 + packages/create-app/package.json | 2 +- packages/dev-utils/CHANGELOG.md | 14 + packages/dev-utils/package.json | 2 +- packages/e2e-test/CHANGELOG.md | 9 + packages/e2e-test/package.json | 2 +- packages/frontend-app-api/CHANGELOG.md | 23 + packages/frontend-app-api/package.json | 2 +- packages/frontend-plugin-api/CHANGELOG.md | 21 + packages/frontend-plugin-api/package.json | 2 +- packages/frontend-test-utils/CHANGELOG.md | 12 + packages/frontend-test-utils/package.json | 2 +- packages/repo-tools/CHANGELOG.md | 24 + packages/repo-tools/package.json | 2 +- .../techdocs-cli-embedded-app/CHANGELOG.md | 19 + .../techdocs-cli-embedded-app/package.json | 2 +- packages/techdocs-cli/CHANGELOG.md | 11 + packages/techdocs-cli/package.json | 2 +- packages/test-utils/CHANGELOG.md | 13 + packages/test-utils/package.json | 2 +- packages/theme/CHANGELOG.md | 6 + packages/theme/package.json | 2 +- plugins/adr-backend/CHANGELOG.md | 15 + plugins/adr-backend/package.json | 2 +- plugins/adr/CHANGELOG.md | 17 + plugins/adr/package.json | 2 +- plugins/airbrake-backend/CHANGELOG.md | 9 + plugins/airbrake-backend/package.json | 2 +- plugins/airbrake/CHANGELOG.md | 13 + plugins/airbrake/package.json | 2 +- plugins/allure/CHANGELOG.md | 11 + plugins/allure/package.json | 2 +- plugins/analytics-module-ga/CHANGELOG.md | 10 + plugins/analytics-module-ga/package.json | 2 +- plugins/analytics-module-ga4/CHANGELOG.md | 10 + plugins/analytics-module-ga4/package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- plugins/apache-airflow/CHANGELOG.md | 8 + plugins/apache-airflow/package.json | 2 +- plugins/api-docs/CHANGELOG.md | 12 + plugins/api-docs/package.json | 2 +- plugins/apollo-explorer/CHANGELOG.md | 9 + plugins/apollo-explorer/package.json | 2 +- plugins/app-backend/CHANGELOG.md | 12 + plugins/app-backend/package.json | 2 +- plugins/app-node/CHANGELOG.md | 7 + plugins/app-node/package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- plugins/auth-backend/CHANGELOG.md | 25 + plugins/auth-backend/package.json | 2 +- plugins/auth-node/CHANGELOG.md | 14 + plugins/auth-node/package.json | 2 +- plugins/azure-devops-backend/CHANGELOG.md | 14 + plugins/azure-devops-backend/package.json | 2 +- plugins/azure-devops/CHANGELOG.md | 13 + plugins/azure-devops/package.json | 2 +- plugins/azure-sites-backend/CHANGELOG.md | 9 + plugins/azure-sites-backend/package.json | 2 +- plugins/azure-sites/CHANGELOG.md | 12 + plugins/azure-sites/package.json | 2 +- plugins/badges-backend/CHANGELOG.md | 13 + plugins/badges-backend/package.json | 2 +- plugins/badges/CHANGELOG.md | 12 + plugins/badges/package.json | 2 +- plugins/bazaar-backend/CHANGELOG.md | 11 + plugins/bazaar-backend/package.json | 2 +- plugins/bazaar/CHANGELOG.md | 13 + plugins/bazaar/package.json | 2 +- plugins/bitrise/CHANGELOG.md | 11 + plugins/bitrise/package.json | 2 +- .../catalog-backend-module-aws/CHANGELOG.md | 19 + .../catalog-backend-module-aws/package.json | 2 +- .../catalog-backend-module-azure/CHANGELOG.md | 17 + .../catalog-backend-module-azure/package.json | 2 +- .../CHANGELOG.md | 14 + .../package.json | 2 +- .../CHANGELOG.md | 18 + .../package.json | 2 +- .../CHANGELOG.md | 15 + .../package.json | 2 +- .../CHANGELOG.md | 14 + .../package.json | 2 +- .../catalog-backend-module-gcp/CHANGELOG.md | 14 + .../catalog-backend-module-gcp/package.json | 2 +- .../CHANGELOG.md | 15 + .../package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 18 + .../package.json | 2 +- .../CHANGELOG.md | 14 + .../package.json | 2 +- .../CHANGELOG.md | 17 + .../package.json | 2 +- .../catalog-backend-module-ldap/CHANGELOG.md | 13 + .../catalog-backend-module-ldap/package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 14 + .../package.json | 2 +- .../CHANGELOG.md | 15 + .../package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- plugins/catalog-backend/CHANGELOG.md | 29 + plugins/catalog-backend/package.json | 2 +- plugins/catalog-graph/CHANGELOG.md | 13 + plugins/catalog-graph/package.json | 2 +- plugins/catalog-import/CHANGELOG.md | 20 + plugins/catalog-import/package.json | 2 +- plugins/catalog-node/CHANGELOG.md | 19 + plugins/catalog-node/package.json | 2 +- plugins/catalog-react/CHANGELOG.md | 21 + plugins/catalog-react/package.json | 2 +- .../catalog-unprocessed-entities/CHANGELOG.md | 11 + .../catalog-unprocessed-entities/package.json | 2 +- plugins/catalog/CHANGELOG.md | 24 + plugins/catalog/package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- plugins/cicd-statistics/CHANGELOG.md | 9 + plugins/cicd-statistics/package.json | 2 +- plugins/circleci/CHANGELOG.md | 11 + plugins/circleci/package.json | 2 +- plugins/cloudbuild/CHANGELOG.md | 11 + plugins/cloudbuild/package.json | 2 +- plugins/code-climate/CHANGELOG.md | 11 + plugins/code-climate/package.json | 2 +- plugins/code-coverage-backend/CHANGELOG.md | 14 + plugins/code-coverage-backend/package.json | 2 +- plugins/code-coverage/CHANGELOG.md | 13 + plugins/code-coverage/package.json | 2 +- plugins/codescene/CHANGELOG.md | 11 + plugins/codescene/package.json | 2 +- plugins/config-schema/CHANGELOG.md | 12 + plugins/config-schema/package.json | 2 +- plugins/cost-insights/CHANGELOG.md | 13 + plugins/cost-insights/package.json | 2 +- plugins/devtools-backend/CHANGELOG.md | 17 + plugins/devtools-backend/package.json | 2 +- plugins/devtools/CHANGELOG.md | 13 + plugins/devtools/package.json | 2 +- plugins/dynatrace/CHANGELOG.md | 11 + plugins/dynatrace/package.json | 2 +- plugins/entity-feedback-backend/CHANGELOG.md | 13 + plugins/entity-feedback-backend/package.json | 2 +- plugins/entity-feedback/CHANGELOG.md | 13 + plugins/entity-feedback/package.json | 2 +- plugins/entity-validation/CHANGELOG.md | 14 + plugins/entity-validation/package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../events-backend-module-azure/CHANGELOG.md | 9 + .../events-backend-module-azure/package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- .../events-backend-module-gerrit/CHANGELOG.md | 9 + .../events-backend-module-gerrit/package.json | 2 +- .../events-backend-module-github/CHANGELOG.md | 10 + .../events-backend-module-github/package.json | 2 +- .../events-backend-module-gitlab/CHANGELOG.md | 10 + .../events-backend-module-gitlab/package.json | 2 +- .../events-backend-test-utils/CHANGELOG.md | 7 + .../events-backend-test-utils/package.json | 2 +- plugins/events-backend/CHANGELOG.md | 11 + plugins/events-backend/package.json | 2 +- plugins/events-node/CHANGELOG.md | 7 + plugins/events-node/package.json | 2 +- .../example-todo-list-backend/CHANGELOG.md | 11 + .../example-todo-list-backend/package.json | 2 +- plugins/example-todo-list/CHANGELOG.md | 9 + plugins/example-todo-list/package.json | 2 +- plugins/explore-backend/CHANGELOG.md | 12 + plugins/explore-backend/package.json | 2 +- plugins/explore/CHANGELOG.md | 18 + plugins/explore/package.json | 2 +- plugins/firehydrant/CHANGELOG.md | 11 + plugins/firehydrant/package.json | 2 +- plugins/fossa/CHANGELOG.md | 12 + plugins/fossa/package.json | 2 +- plugins/gcalendar/CHANGELOG.md | 10 + plugins/gcalendar/package.json | 2 +- plugins/gcp-projects/CHANGELOG.md | 9 + plugins/gcp-projects/package.json | 2 +- plugins/git-release-manager/CHANGELOG.md | 10 + plugins/git-release-manager/package.json | 2 +- plugins/github-actions/CHANGELOG.md | 13 + plugins/github-actions/package.json | 2 +- plugins/github-deployments/CHANGELOG.md | 14 + plugins/github-deployments/package.json | 2 +- plugins/github-issues/CHANGELOG.md | 13 + plugins/github-issues/package.json | 2 +- .../github-pull-requests-board/CHANGELOG.md | 12 + .../github-pull-requests-board/package.json | 2 +- plugins/gitops-profiles/CHANGELOG.md | 10 + plugins/gitops-profiles/package.json | 2 +- plugins/gocd/CHANGELOG.md | 12 + plugins/gocd/package.json | 2 +- plugins/graphiql/CHANGELOG.md | 14 + plugins/graphiql/package.json | 2 +- plugins/graphql-voyager/CHANGELOG.md | 9 + plugins/graphql-voyager/package.json | 2 +- plugins/home-react/CHANGELOG.md | 8 + plugins/home-react/package.json | 2 +- plugins/home/CHANGELOG.md | 21 + plugins/home/package.json | 2 +- plugins/ilert/CHANGELOG.md | 12 + plugins/ilert/package.json | 2 +- plugins/jenkins-backend/CHANGELOG.md | 17 + plugins/jenkins-backend/package.json | 2 +- plugins/jenkins/CHANGELOG.md | 13 + plugins/jenkins/package.json | 2 +- plugins/kafka-backend/CHANGELOG.md | 11 + plugins/kafka-backend/package.json | 2 +- plugins/kafka/CHANGELOG.md | 12 + plugins/kafka/package.json | 2 +- plugins/kubernetes-backend/CHANGELOG.md | 20 + plugins/kubernetes-backend/package.json | 2 +- plugins/kubernetes-cluster/CHANGELOG.md | 15 + plugins/kubernetes-cluster/package.json | 2 +- plugins/kubernetes-node/CHANGELOG.md | 9 + plugins/kubernetes-node/package.json | 2 +- plugins/kubernetes-react/CHANGELOG.md | 19 + plugins/kubernetes-react/package.json | 2 +- plugins/kubernetes/CHANGELOG.md | 21 + plugins/kubernetes/package.json | 2 +- plugins/lighthouse-backend/CHANGELOG.md | 19 + plugins/lighthouse-backend/package.json | 2 +- plugins/lighthouse/CHANGELOG.md | 14 + plugins/lighthouse/package.json | 2 +- plugins/linguist-backend/CHANGELOG.md | 17 + plugins/linguist-backend/package.json | 2 +- plugins/linguist/CHANGELOG.md | 13 + plugins/linguist/package.json | 2 +- plugins/microsoft-calendar/CHANGELOG.md | 10 + plugins/microsoft-calendar/package.json | 2 +- plugins/newrelic-dashboard/CHANGELOG.md | 11 + plugins/newrelic-dashboard/package.json | 2 +- plugins/newrelic/CHANGELOG.md | 9 + plugins/newrelic/package.json | 2 +- plugins/nomad-backend/CHANGELOG.md | 10 + plugins/nomad-backend/package.json | 2 +- plugins/nomad/CHANGELOG.md | 12 + plugins/nomad/package.json | 2 +- plugins/octopus-deploy/CHANGELOG.md | 11 + plugins/octopus-deploy/package.json | 2 +- plugins/opencost/CHANGELOG.md | 9 + plugins/opencost/package.json | 2 +- plugins/org-react/CHANGELOG.md | 12 + plugins/org-react/package.json | 2 +- plugins/org/CHANGELOG.md | 11 + plugins/org/package.json | 2 +- plugins/pagerduty/CHANGELOG.md | 13 + plugins/pagerduty/package.json | 2 +- plugins/periskop-backend/CHANGELOG.md | 9 + plugins/periskop-backend/package.json | 2 +- plugins/periskop/CHANGELOG.md | 12 + plugins/periskop/package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- plugins/permission-backend/CHANGELOG.md | 13 + plugins/permission-backend/package.json | 2 +- plugins/permission-node/CHANGELOG.md | 12 + plugins/permission-node/package.json | 2 +- plugins/playlist-backend/CHANGELOG.md | 16 + plugins/playlist-backend/package.json | 2 +- plugins/playlist/CHANGELOG.md | 17 + plugins/playlist/package.json | 2 +- plugins/proxy-backend/CHANGELOG.md | 9 + plugins/proxy-backend/package.json | 2 +- plugins/puppetdb/CHANGELOG.md | 12 + plugins/puppetdb/package.json | 2 +- plugins/rollbar-backend/CHANGELOG.md | 8 + plugins/rollbar-backend/package.json | 2 +- plugins/rollbar/CHANGELOG.md | 11 + plugins/rollbar/package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- plugins/scaffolder-backend/CHANGELOG.md | 24 + plugins/scaffolder-backend/package.json | 2 +- plugins/scaffolder-node/CHANGELOG.md | 13 + plugins/scaffolder-node/package.json | 2 +- plugins/scaffolder-react/CHANGELOG.md | 17 + plugins/scaffolder-react/package.json | 2 +- plugins/scaffolder/CHANGELOG.md | 21 + plugins/scaffolder/package.json | 2 +- .../CHANGELOG.md | 19 + .../package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 14 + .../package.json | 2 +- plugins/search-backend-module-pg/CHANGELOG.md | 12 + plugins/search-backend-module-pg/package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 19 + .../package.json | 2 +- plugins/search-backend-node/CHANGELOG.md | 13 + plugins/search-backend-node/package.json | 2 +- plugins/search-backend/CHANGELOG.md | 17 + plugins/search-backend/package.json | 2 +- plugins/search-react/CHANGELOG.md | 14 + plugins/search-react/package.json | 2 +- plugins/search/CHANGELOG.md | 22 + plugins/search/package.json | 2 +- plugins/sentry/CHANGELOG.md | 11 + plugins/sentry/package.json | 2 +- plugins/shortcuts/CHANGELOG.md | 10 + plugins/shortcuts/package.json | 2 +- plugins/sonarqube-backend/CHANGELOG.md | 10 + plugins/sonarqube-backend/package.json | 2 +- plugins/sonarqube/CHANGELOG.md | 12 + plugins/sonarqube/package.json | 2 +- plugins/splunk-on-call/CHANGELOG.md | 11 + plugins/splunk-on-call/package.json | 2 +- plugins/stack-overflow-backend/CHANGELOG.md | 10 + plugins/stack-overflow-backend/package.json | 2 +- plugins/stack-overflow/CHANGELOG.md | 15 + plugins/stack-overflow/package.json | 2 +- plugins/stackstorm/CHANGELOG.md | 10 + plugins/stackstorm/package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- plugins/tech-insights-backend/CHANGELOG.md | 15 + plugins/tech-insights-backend/package.json | 2 +- plugins/tech-insights-node/CHANGELOG.md | 11 + plugins/tech-insights-node/package.json | 2 +- plugins/tech-insights/CHANGELOG.md | 14 + plugins/tech-insights/package.json | 2 +- plugins/tech-radar/CHANGELOG.md | 13 + plugins/tech-radar/package.json | 2 +- .../techdocs-addons-test-utils/CHANGELOG.md | 17 + .../techdocs-addons-test-utils/package.json | 2 +- plugins/techdocs-backend/CHANGELOG.md | 18 + plugins/techdocs-backend/package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- plugins/techdocs-node/CHANGELOG.md | 14 + plugins/techdocs-node/package.json | 2 +- plugins/techdocs-react/CHANGELOG.md | 11 + plugins/techdocs-react/package.json | 2 +- plugins/techdocs/CHANGELOG.md | 22 + plugins/techdocs/package.json | 2 +- plugins/todo-backend/CHANGELOG.md | 15 + plugins/todo-backend/package.json | 2 +- plugins/todo/CHANGELOG.md | 12 + plugins/todo/package.json | 2 +- plugins/user-settings-backend/CHANGELOG.md | 13 + plugins/user-settings-backend/package.json | 2 +- plugins/user-settings/CHANGELOG.md | 18 + plugins/user-settings/package.json | 2 +- plugins/vault-backend/CHANGELOG.md | 12 + plugins/vault-backend/package.json | 2 +- plugins/vault-node/CHANGELOG.md | 7 + plugins/vault-node/package.json | 2 +- plugins/vault/CHANGELOG.md | 12 + plugins/vault/package.json | 2 +- plugins/xcmetrics/CHANGELOG.md | 10 + plugins/xcmetrics/package.json | 2 +- 435 files changed, 6310 insertions(+), 218 deletions(-) create mode 100644 docs/releases/v1.21.0-next.3-changelog.md diff --git a/.changeset/pre.json b/.changeset/pre.json index 69d9cbf255..245e7d7dd1 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -266,8 +266,10 @@ "angry-walls-juggle", "big-swans-guess", "blue-meals-chew", + "brave-beers-happen", "brave-parents-stare", "brave-socks-raise", + "breezy-houses-eat", "breezy-pans-glow", "bright-eyes-film", "brown-books-carry", @@ -275,56 +277,78 @@ "chilled-buses-love", "chilled-terms-breathe", "chilly-bikes-kick", + "chilly-lies-collect", + "clean-clouds-fry", "clever-wombats-sneeze", "cold-pans-crash", "cool-knives-argue", "create-app-1700579510", "create-app-1700607979", "curly-walls-relate", + "dirty-turkeys-reflect", "dry-readers-raise", + "eighty-dodos-sing", + "eighty-phones-peel", "eleven-ants-pretend", "empty-dingos-grow", "empty-fireants-study", + "fair-plants-attack", "famous-flies-kick", "famous-peas-reflect", "fifty-cameras-share", "fifty-seas-grab", "five-feet-call", "forty-clocks-hug", + "forty-insects-drop", + "forty-mirrors-carry", + "four-foxes-juggle", "four-needles-watch", "funny-bobcats-try", "gentle-lies-greet", + "gentle-timers-fail", "giant-files-fry", "gold-humans-tease", "gold-shirts-yell", + "good-wolves-leave", "gorgeous-snails-admire", "great-rings-type", "green-seals-play", "healthy-feet-kick", "healthy-poets-search", "hip-berries-begin", + "hip-cars-repair", "honest-houses-hide", "hot-wolves-flash", "hungry-buckets-compare", + "itchy-camels-cough", "khaki-clocks-happen", "khaki-hounds-think", "kind-badgers-rush", "kind-cycles-happen", "large-weeks-accept", + "late-eyes-serve", + "late-hats-beam", + "light-beers-cheer", "little-suits-collect", + "long-cycles-grow", "long-wolves-return", "lovely-terms-search", "lucky-kids-cough", "metal-eggs-smile", "mighty-beans-wink", "modern-mails-live", + "nasty-rockets-bathe", "nasty-tips-exercise", "nervous-dancers-wait", + "nervous-ladybugs-end", "nervous-penguins-sort", + "ninety-otters-report", + "orange-boats-hunt", "perfect-apes-sing", "perfect-crabs-help", "pink-dryers-repair", "plenty-numbers-enjoy", + "polite-crabs-build", "polite-knives-build", "poor-pandas-dream", "pretty-onions-knock", @@ -332,9 +356,16 @@ "proud-flies-travel", "proud-seahorses-explain", "quick-horses-reply", + "quick-lions-care", "real-bees-thank", + "red-readers-search", + "renovate-0392ef9", "renovate-07b1766", + "renovate-0c44581", + "renovate-1252136", + "renovate-12c95fb", "renovate-169bdc2", + "renovate-19742c3", "renovate-1ed81a0", "renovate-240982c", "renovate-4891ee7", @@ -346,29 +377,42 @@ "renovate-796bd6f", "renovate-8d8b90d", "renovate-9d2d52e", + "renovate-a277605", "renovate-a6399d6", "renovate-b193efa", "renovate-c4e012c", "renovate-c7270d5", + "renovate-c727667", "renovate-dee7ad1", "renovate-ead3ba6", "renovate-f5b18be", + "rich-bees-breathe", "rich-singers-join", "rude-beans-drop", "rude-ears-greet", + "sharp-dingos-learn", + "shiny-books-search", "silent-rats-reflect", "silly-numbers-wash", "silver-rocks-deliver", + "six-cooks-attack", "sixty-adults-kiss", "sixty-houses-agree", + "slow-bottles-cross", "slow-trees-warn", "smooth-frogs-decide", "sour-pumas-reply", "spotty-olives-share", + "spotty-terms-occur", "stale-bats-end", + "stale-frogs-agree", "stale-walls-cross", + "strange-brooms-poke", "strange-suits-glow", + "stupid-wasps-fold", "tame-pants-end", + "tasty-dolphins-unite", + "ten-snakes-wait", "tender-peas-smoke", "thick-snails-travel", "thirty-fireants-cheer", @@ -379,6 +423,10 @@ "unlucky-clouds-build", "violet-zebras-thank", "warm-plums-beg", - "wicked-elephants-think" + "wet-bananas-agree", + "wicked-elephants-think", + "wicked-pants-end", + "wild-knives-wait", + "witty-cars-wash" ] } diff --git a/docs/releases/v1.21.0-next.3-changelog.md b/docs/releases/v1.21.0-next.3-changelog.md new file mode 100644 index 0000000000..a45c6d6df0 --- /dev/null +++ b/docs/releases/v1.21.0-next.3-changelog.md @@ -0,0 +1,3025 @@ +# Release v1.21.0-next.3 + +## @backstage/config-loader@1.6.0-next.0 + +### Minor Changes + +- 24f5a85: Add "path" to `TransformFunc` context + +### Patch Changes + +- Updated dependencies + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/core-compat-api@0.1.0-next.2 + +### Minor Changes + +- cf5cc4c: Discover plugins and routes recursively beneath the root routes in `collectLecacyRoutes` + +### Patch Changes + +- 8226442: Added `compatWrapper`, which can be used to wrap any React element to provide bi-directional interoperability between the `@backstage/core-*-api` and `@backstage/frontend-*-api` APIs. +- 8f5d6c1: Updates to match the new extension input wrapping. +- b7adf24: Delete alpha DI compatibility helper for components, migrating components should be simple without a helper. +- 046e443: Updates for compatibility with the new extension IDs. +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/core-app-api@1.11.2-next.1 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/frontend-app-api@0.4.0-next.2 + +### Minor Changes + +- ea06590: The app no longer provides the `AppContext` from `@backstage/core-plugin-api`. Components that require this context to be available should use the `compatWrapper` helper from `@backstage/core-compat-api`. + +### Patch Changes + +- aeb8008: Add support for translation extensions. +- b7adf24: Use the new plugin type for error boundary components. +- 8f5d6c1: Updates to match the new extension input wrapping. +- cb4197a: Forward ` node`` instead of `extensionId\` to resolved extension inputs. +- 8837a96: Updates to match the introduction of `ExtensionDefinition` and new extension ID naming patterns. +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/theme@0.5.0-next.1 + - @backstage/config@1.1.1 + - @backstage/core-app-api@1.11.2-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/frontend-plugin-api@0.4.0-next.2 + +### Minor Changes + +- 8f5d6c1: Extension inputs are now wrapped into an additional object when passed to the extension factory, with the previous values being available at the `output` property. The `ExtensionInputValues` type has also been replaced by `ResolvedExtensionInputs`. +- 8837a96: **BREAKING**: This version changes how extensions are created and how their IDs are determined. The `createExtension` function now accepts `kind`, `namespace` and `name` instead of `id`. All of the new options are optional, and are used to construct the final extension ID. By convention extension creators should set the `kind` to match their own name, for example `createNavItemExtension` sets the kind `nav-item`. + + The `createExtension` function as well as all extension creators now also return an `ExtensionDefinition` rather than an `Extension`, which in turn needs to be passed to `createPlugin` or `createExtensionOverrides` to be used. + +### Patch Changes + +- b7adf24: Update alpha component ref type to be more specific than any, delete boot page component and use new plugin type for error boundary component extensions. +- 73246ec: Added translation APIs as well as `createTranslationExtension`. +- cb4197a: Forward ` node`` instead of `extensionId\` to resolved extension inputs. +- Updated dependencies + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/plugin-catalog-backend@1.16.0-next.2 + +### Minor Changes + +- 7804597: Permission rules can now be added for the Catalog plugin through the `CatalogPermissionExtensionPoint` interface. + +### Patch Changes + +- 50ee804: Wrap single `pipelineLoop` of TaskPipeline in a span for better traces +- a168507: Deprecated `EntitiesSearchFilter` and `EntityFilter`, which can now be imported from `@backstage/plugin-catalog-node` instead +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/plugin-search-backend-module-catalog@0.1.12-next.2 + - @backstage/backend-openapi-utils@0.1.1-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.18 + - @backstage/plugin-events-node@0.2.17-next.2 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-permission-node@0.7.19-next.2 + +## @backstage/plugin-catalog-node@1.6.0-next.2 + +### Minor Changes + +- a168507: Added `EntitiesSearchFilter` and `EntityFilter` from `@backstage/plugin-catalog-backend`, for reuse +- 7804597: Permission rules can now be added for the Catalog plugin through the `CatalogPermissionExtensionPoint` interface. + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.18 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-permission-node@0.7.19-next.2 + +## @backstage/plugin-kubernetes-react@0.2.0-next.2 + +### Minor Changes + +- 899d71a: Change `formatClusterLink` to be an API and make it async for further customization possibilities. + + **BREAKING** + If you have a custom k8s page and used `formatClusterLink` directly, you need to migrate to new `kubernetesClusterLinkFormatterApiRef` + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.7.2-next.1 + +## @backstage/plugin-lighthouse-backend@0.4.0-next.2 + +### Minor Changes + +- 7f0dbfd: Fixed crashes faced with custom schedule configuration. The configuration schema has been update to leverage the TaskScheduleDefinition interface. It is highly recommended to move the `lighthouse.shedule` and `lighthouse.timeout` respectively to `lighthouse.schedule.frequency` and `lighthouse.schedule.timeout`. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/plugin-lighthouse-common@0.1.4 + +## @backstage/app-defaults@1.4.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/core-app-api@1.11.2-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/plugin-permission-react@0.4.18-next.1 + +## @backstage/backend-app-api@0.5.9-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.6.0-next.0 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/cli-common@0.1.13 + - @backstage/cli-node@0.2.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-node@0.7.19-next.2 + +## @backstage/backend-common@0.20.0-next.2 + +### Patch Changes + +- bc67498: Updated dependency `archiver` to `^6.0.0`. + Updated dependency `@types/archiver` to `^6.0.0`. +- Updated dependencies + - @backstage/config-loader@1.6.0-next.0 + - @backstage/backend-app-api@0.5.9-next.2 + - @backstage/backend-dev-utils@0.1.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/integration-aws-node@0.1.8 + - @backstage/types@1.1.1 + +## @backstage/backend-defaults@0.2.8-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-app-api@0.5.9-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + +## @backstage/backend-openapi-utils@0.1.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/backend-plugin-api@0.6.8-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.10 + +## @backstage/backend-tasks@0.5.13-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/backend-test-utils@0.2.9-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-app-api@0.5.9-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/catalog-client@1.5.0-next.1 + +### Patch Changes + +- 82fa88b: Fixes a bug where some query parameters were double URL encoded. +- Updated dependencies + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + +## @backstage/cli@0.25.0-next.2 + +### Patch Changes + +- 32018ff: Enable the `tsx` loader to work on Node 18.19 and up +- a3edc18: Updated dependency `vite-plugin-node-polyfills` to `^0.17.0`. +- 627554e: Updated dependency `@rollup/plugin-node-resolve` to `^15.0.0`. +- c07cee5: Updated dependency `@rollup/plugin-json` to `^6.0.0`. +- 2565cc8: Updated dependency `@rollup/plugin-commonjs` to `^25.0.0`. +- Updated dependencies + - @backstage/config-loader@1.6.0-next.0 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/cli-node@0.2.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/eslint-plugin@0.1.4-next.0 + - @backstage/integration@1.8.0-next.1 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + +## @backstage/core-components@0.13.9-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/config@1.1.1 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/version-bridge@1.0.7 + +## @backstage/create-app@0.5.8-next.3 + +### Patch Changes + +- a96c2d4: Include the `` for group entities by default +- Updated dependencies + - @backstage/cli-common@0.1.13 + +## @backstage/dev-utils@1.0.25-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/app-defaults@1.4.6-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-app-api@1.11.2-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/integration-react@1.1.22-next.1 + +## @backstage/frontend-test-utils@0.1.0-next.2 + +### Patch Changes + +- 818eea4: Updates for compatibility with the new extension IDs. +- b9aa6e4: Migrate `renderInTestApp` to `@backstage/frontend-test-utils` for testing individual React components in an app. +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/frontend-app-api@0.4.0-next.2 + - @backstage/test-utils@1.4.6-next.2 + - @backstage/types@1.1.1 + +## @backstage/repo-tools@0.5.0-next.1 + +### Patch Changes + +- f909e9d: Includes templates in @backstage/repo-tools package and use them in the CLI + +- da3c4db: Updates the `schema openapi generate-client` command to export all generated types from the generated directory. + +- 7959f23: The `api-reports` command now checks for api report files that no longer apply. + If it finds such files, it's treated basically the same as report errors do, and + the check fails. + + For example, if you had an `api-report-alpha.md` but then removed the alpha + export, the reports generator would now report that this file needs to be + deleted. + +- f49e237: Fixed a bug where `schema openapi init` created an invalid test command. + +- f91be2c: Updated dependency `@stoplight/types` to `^14.0.0`. + +- 45bfb20: Execute `openapi-generator-cli` from `@backstage/repo-tools` directory to force it to use our openapitools.json config file. + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/cli-node@0.2.0 + - @backstage/errors@1.2.3 + +## @techdocs/cli@1.8.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/plugin-techdocs-node@1.11.0-next.2 + +## @backstage/test-utils@1.4.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/config@1.1.1 + - @backstage/core-app-api@1.11.2-next.1 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-permission-react@0.4.18-next.1 + +## @backstage/theme@0.5.0-next.1 + +### Patch Changes + +- cd0dd4c: Align Material UI v5 `Paper` component background color in dark mode to v4. + +## @backstage/plugin-adr@0.6.11-next.2 + +### Patch Changes + +- 36c94b8: Refactor of the alpha exports due to API change in how extension IDs are constructed. +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/plugin-search-react@1.7.4-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/integration-react@1.1.22-next.1 + - @backstage/plugin-adr-common@0.2.18-next.1 + - @backstage/plugin-search-common@1.2.8 + +## @backstage/plugin-adr-backend@0.4.5-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/plugin-adr-common@0.2.18-next.1 + - @backstage/plugin-search-common@1.2.8 + +## @backstage/plugin-airbrake@0.3.28-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/dev-utils@1.0.25-next.2 + - @backstage/test-utils@1.4.6-next.2 + +## @backstage/plugin-airbrake-backend@0.3.5-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + +## @backstage/plugin-allure@0.1.44-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + +## @backstage/plugin-analytics-module-ga@0.1.36-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + +## @backstage/plugin-analytics-module-ga4@0.1.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + +## @backstage/plugin-analytics-module-newrelic-browser@0.0.5-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + +## @backstage/plugin-apache-airflow@0.2.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + +## @backstage/plugin-api-docs@0.10.2-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog@1.16.0-next.3 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + +## @backstage/plugin-apollo-explorer@0.1.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + +## @backstage/plugin-app-backend@0.3.56-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.6.0-next.0 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.8-next.2 + +## @backstage/plugin-app-node@0.1.8-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.8-next.2 + +## @backstage/plugin-auth-backend@0.20.1-next.2 + +### Patch Changes + +- 783797a: fix static token issuer not being able to initialize +- a62764b: Updated dependency `passport` to `^0.7.0`. +- Updated dependencies + - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.0-next.1 + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-backend-module-atlassian-provider@0.1.0-next.2 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.1.5-next.2 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.1.5-next.2 + - @backstage/plugin-auth-backend-module-okta-provider@0.0.1-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.2-next.2 + - @backstage/plugin-auth-backend-module-google-provider@0.1.5-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-backend-module-github-provider@0.1.5-next.2 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.1.0-next.2 + +### Patch Changes + +- a62764b: Updated dependency `passport` to `^0.7.0`. +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.2-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-backend-module-github-provider@0.1.5-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.1.5-next.2 + +### Patch Changes + +- a62764b: Updated dependency `passport` to `^0.7.0`. +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + +## @backstage/plugin-auth-backend-module-google-provider@0.1.5-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.1.3-next.2 + +### Patch Changes + +- a62764b: Updated dependency `passport` to `^0.7.0`. +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.1.5-next.2 + +### Patch Changes + +- a62764b: Updated dependency `passport` to `^0.7.0`. +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.0-next.1 + +### Patch Changes + +- a6be465: Exported the provider as default so it gets discovered when using `featureDiscoveryServiceFactory()` +- 510dab4: Change provider id from `oauth2ProxyProvider` to `oauth2Proxy` +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/errors@1.2.3 + +## @backstage/plugin-auth-backend-module-okta-provider@0.0.1-next.2 + +### Patch Changes + +- a62764b: Updated dependency `passport` to `^0.7.0`. +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.1.2-next.2 + +### Patch Changes + +- a62764b: Updated dependency `passport` to `^0.7.0`. +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.1.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + +## @backstage/plugin-auth-node@0.4.2-next.2 + +### Patch Changes + +- a62764b: Updated dependency `passport` to `^0.7.0`. +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-azure-devops@0.3.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-azure-devops-common@0.3.2-next.0 + +## @backstage/plugin-azure-devops-backend@0.5.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/integration@1.8.0-next.1 + - @backstage/plugin-azure-devops-common@0.3.2-next.0 + - @backstage/plugin-catalog-common@1.0.18 + +## @backstage/plugin-azure-sites@0.1.17-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/plugin-azure-sites-common@0.1.1 + +## @backstage/plugin-azure-sites-backend@0.1.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/config@1.1.1 + - @backstage/plugin-azure-sites-common@0.1.1 + +## @backstage/plugin-badges@0.2.52-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-badges-backend@0.3.5-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-bazaar@0.2.20-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-bazaar-backend@0.3.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-bitrise@0.1.55-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + +## @backstage/plugin-catalog@1.16.0-next.3 + +### Patch Changes + +- a1227cc: Wrap `/alpha` export extension elements in backwards compatibility wrapper. +- 8f5d6c1: Updates to the `/alpha` exports to match the extension input wrapping change. +- 36c94b8: Refactor of the alpha exports due to API change in how extension IDs are constructed. +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/theme@0.5.0-next.1 + - @backstage/core-compat-api@0.1.0-next.2 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/plugin-search-react@1.7.4-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/integration-react@1.1.22-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.18 + - @backstage/plugin-scaffolder-common@1.4.3 + - @backstage/plugin-search-common@1.2.8 + +## @backstage/plugin-catalog-backend-module-aws@0.3.2-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/integration-aws-node@0.1.8 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.18 + - @backstage/plugin-kubernetes-common@0.7.2-next.1 + +## @backstage/plugin-catalog-backend-module-azure@0.1.27-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.18 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.1.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-openapi-utils@0.1.1-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-catalog-backend-module-bitbucket@0.2.23-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-bitbucket-cloud-common@0.2.15-next.1 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.1.23-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/integration@1.8.0-next.1 + - @backstage/plugin-bitbucket-cloud-common@0.2.15-next.1 + - @backstage/plugin-catalog-common@1.0.18 + - @backstage/plugin-events-node@0.2.17-next.2 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.1.21-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + +## @backstage/plugin-catalog-backend-module-gcp@0.1.8-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/plugin-kubernetes-common@0.7.2-next.1 + +## @backstage/plugin-catalog-backend-module-gerrit@0.1.24-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + +## @backstage/plugin-catalog-backend-module-github@0.4.6-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/plugin-catalog-backend@1.16.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/integration@1.8.0-next.1 + - @backstage/plugin-catalog-common@1.0.18 + - @backstage/plugin-events-node@0.2.17-next.2 + +## @backstage/plugin-catalog-backend-module-github-org@0.1.2-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-catalog-backend-module-github@0.4.6-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/config@1.1.1 + +## @backstage/plugin-catalog-backend-module-gitlab@0.3.5-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/integration@1.8.0-next.1 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.4.12-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/plugin-catalog-backend@1.16.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-events-node@0.2.17-next.2 + - @backstage/plugin-permission-common@0.7.10 + +## @backstage/plugin-catalog-backend-module-ldap@0.5.23-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.18 + +## @backstage/plugin-catalog-backend-module-msgraph@0.5.15-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/plugin-catalog-common@1.0.18 + +## @backstage/plugin-catalog-backend-module-openapi@0.1.25-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/plugin-catalog-backend@1.16.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/integration@1.8.0-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.18 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.1.13-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.5-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/plugin-catalog-common@1.0.18 + - @backstage/plugin-scaffolder-common@1.4.3 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.3.5-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + +## @backstage/plugin-catalog-graph@0.3.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-import@0.10.4-next.3 + +### Patch Changes + +- a1227cc: Wrap `/alpha` export extension elements in backwards compatibility wrapper. +- 36c94b8: Refactor of the alpha exports due to API change in how extension IDs are constructed. +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/core-compat-api@0.1.0-next.2 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/integration-react@1.1.22-next.1 + - @backstage/plugin-catalog-common@1.0.18 + +## @backstage/plugin-catalog-react@1.9.2-next.2 + +### Patch Changes + +- 8f5d6c1: Updates to the `/alpha` exports to match the extension input wrapping change. +- 36c94b8: Refactor of the alpha exports due to API change in how extension IDs are constructed. +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/theme@0.5.0-next.1 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/integration-react@1.1.22-next.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-catalog-common@1.0.18 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-permission-react@0.4.18-next.1 + +## @backstage/plugin-catalog-unprocessed-entities@0.1.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-cicd-statistics@0.1.30-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-plugin-api@1.8.1-next.1 + +## @backstage/plugin-cicd-statistics-module-gitlab@0.1.24-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.3 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/plugin-cicd-statistics@0.1.30-next.2 + +## @backstage/plugin-circleci@0.3.28-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + +## @backstage/plugin-cloudbuild@0.3.28-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + +## @backstage/plugin-code-climate@0.1.28-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + +## @backstage/plugin-code-coverage@0.2.21-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-code-coverage-backend@0.2.22-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + +## @backstage/plugin-codescene@0.1.20-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-config-schema@0.1.48-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-cost-insights@0.12.17-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/plugin-cost-insights-common@0.1.2 + +## @backstage/plugin-devtools@0.1.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-devtools-common@0.1.6 + - @backstage/plugin-permission-react@0.4.18-next.1 + +## @backstage/plugin-devtools-backend@0.2.5-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.6.0-next.0 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-devtools-common@0.1.6 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-permission-node@0.7.19-next.2 + +## @backstage/plugin-dynatrace@8.0.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + +## @backstage/plugin-entity-feedback@0.2.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-entity-feedback-common@0.1.3 + +## @backstage/plugin-entity-feedback-backend@0.2.5-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/plugin-entity-feedback-common@0.1.3 + +## @backstage/plugin-entity-validation@0.1.13-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-catalog-common@1.0.18 + +## @backstage/plugin-events-backend@0.2.17-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + - @backstage/plugin-events-node@0.2.17-next.2 + +## @backstage/plugin-events-backend-module-aws-sqs@0.2.11-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.2.17-next.2 + +## @backstage/plugin-events-backend-module-azure@0.1.18-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/plugin-events-node@0.2.17-next.2 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.1.18-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/plugin-events-node@0.2.17-next.2 + +## @backstage/plugin-events-backend-module-gerrit@0.1.18-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/plugin-events-node@0.2.17-next.2 + +## @backstage/plugin-events-backend-module-github@0.1.18-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + - @backstage/plugin-events-node@0.2.17-next.2 + +## @backstage/plugin-events-backend-module-gitlab@0.1.18-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + - @backstage/plugin-events-node@0.2.17-next.2 + +## @backstage/plugin-events-backend-test-utils@0.1.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.2.17-next.2 + +## @backstage/plugin-events-node@0.2.17-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.8-next.2 + +## @backstage/plugin-explore@0.4.14-next.2 + +### Patch Changes + +- 36c94b8: Refactor of the alpha exports due to API change in how extension IDs are constructed. +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/plugin-search-react@1.7.4-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-explore-react@0.0.34-next.1 + - @backstage/plugin-search-common@1.2.8 + +## @backstage/plugin-explore-backend@0.0.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-search-backend-module-explore@0.1.12-next.2 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-search-common@1.2.8 + +## @backstage/plugin-firehydrant@0.2.12-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + +## @backstage/plugin-fossa@0.2.60-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-gcalendar@0.3.21-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-gcp-projects@0.3.44-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + +## @backstage/plugin-git-release-manager@0.3.40-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/integration@1.8.0-next.1 + +## @backstage/plugin-github-actions@0.6.9-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/integration@1.8.0-next.1 + - @backstage/integration-react@1.1.22-next.1 + +## @backstage/plugin-github-deployments@0.1.59-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/integration-react@1.1.22-next.1 + +## @backstage/plugin-github-issues@0.2.17-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + +## @backstage/plugin-github-pull-requests-board@0.1.22-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/integration@1.8.0-next.1 + +## @backstage/plugin-gitops-profiles@0.3.43-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + +## @backstage/plugin-gocd@0.1.34-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-graphiql@0.3.1-next.3 + +### Patch Changes + +- a1227cc: Wrap `/alpha` export extension elements in backwards compatibility wrapper. +- 8f5d6c1: Updates to the `/alpha` exports to match the extension input wrapping change. +- 36c94b8: Refactor of the alpha exports due to API change in how extension IDs are constructed. +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/theme@0.5.0-next.1 + - @backstage/core-compat-api@0.1.0-next.2 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + +## @backstage/plugin-graphql-voyager@0.1.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + +## @backstage/plugin-home@0.6.0-next.2 + +### Patch Changes + +- a1227cc: Wrap `/alpha` export extension elements in backwards compatibility wrapper. +- 8f5d6c1: Updates to the `/alpha` exports to match the extension input wrapping change. +- 36c94b8: Refactor of the alpha exports due to API change in how extension IDs are constructed. +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/theme@0.5.0-next.1 + - @backstage/core-compat-api@0.1.0-next.2 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-app-api@1.11.2-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-home-react@0.1.6-next.2 + +## @backstage/plugin-home-react@0.1.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + +## @backstage/plugin-ilert@0.2.17-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-jenkins@0.9.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-jenkins-common@0.1.21 + +## @backstage/plugin-jenkins-backend@0.3.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-jenkins-common@0.1.21 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-permission-node@0.7.19-next.2 + +## @backstage/plugin-kafka@0.3.28-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + +## @backstage/plugin-kafka-backend@0.3.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-kubernetes@0.11.3-next.2 + +### Patch Changes + +- 899d71a: Change `formatClusterLink` to be an API and make it async for further customization possibilities. + + **BREAKING** + If you have a custom k8s page and used `formatClusterLink` directly, you need to migrate to new `kubernetesClusterLinkFormatterApiRef` + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-kubernetes-react@0.2.0-next.2 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.7.2-next.1 + +## @backstage/plugin-kubernetes-backend@0.14.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration-aws-node@0.1.8 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.7.2-next.1 + - @backstage/plugin-kubernetes-node@0.1.2-next.2 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-permission-node@0.7.19-next.2 + +## @backstage/plugin-kubernetes-cluster@0.0.4-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-kubernetes-react@0.2.0-next.2 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-kubernetes-common@0.7.2-next.1 + +## @backstage/plugin-kubernetes-node@0.1.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/plugin-kubernetes-common@0.7.2-next.1 + +## @backstage/plugin-lighthouse@0.4.13-next.2 + +### Patch Changes + +- ffbf656: Updated README +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/plugin-lighthouse-common@0.1.4 + +## @backstage/plugin-linguist@0.1.13-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-linguist-common@0.1.2 + +## @backstage/plugin-linguist-backend@0.5.5-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-linguist-common@0.1.2 + +## @backstage/plugin-microsoft-calendar@0.1.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-newrelic@0.3.43-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + +## @backstage/plugin-newrelic-dashboard@0.3.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-nomad@0.1.9-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + +## @backstage/plugin-nomad-backend@0.1.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-octopus-deploy@0.2.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + +## @backstage/plugin-opencost@0.2.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + +## @backstage/plugin-org@0.6.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + +## @backstage/plugin-org-react@0.1.17-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + +## @backstage/plugin-pagerduty@0.7.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-home-react@0.1.6-next.2 + +## @backstage/plugin-periskop@0.1.26-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-periskop-backend@0.2.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + +## @backstage/plugin-permission-backend@0.5.31-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-permission-node@0.7.19-next.2 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.1.5-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-permission-node@0.7.19-next.2 + +## @backstage/plugin-permission-node@0.7.19-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-permission-common@0.7.10 + +## @backstage/plugin-playlist@0.2.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/plugin-search-react@1.7.4-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-catalog-common@1.0.18 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-permission-react@0.4.18-next.1 + - @backstage/plugin-playlist-common@0.1.12 + +## @backstage/plugin-playlist-backend@0.3.12-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-permission-node@0.7.19-next.2 + - @backstage/plugin-playlist-common@0.1.12 + +## @backstage/plugin-proxy-backend@0.4.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + +## @backstage/plugin-puppetdb@0.1.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-rollbar@0.4.28-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + +## @backstage/plugin-rollbar-backend@0.1.53-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/config@1.1.1 + +## @backstage/plugin-scaffolder@1.16.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/plugin-scaffolder-react@1.6.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/integration-react@1.1.22-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.18 + - @backstage/plugin-permission-react@0.4.18-next.1 + - @backstage/plugin-scaffolder-common@1.4.3 + +## @backstage/plugin-scaffolder-backend@1.19.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/plugin-catalog-backend@1.16.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.5-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.18 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-permission-node@0.7.19-next.2 + - @backstage/plugin-scaffolder-common@1.4.3 + - @backstage/plugin-scaffolder-node@0.2.9-next.2 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.9-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.2.9-next.2 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.2.32-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.2.9-next.2 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.2.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/plugin-scaffolder-node@0.2.9-next.2 + +## @backstage/plugin-scaffolder-backend-module-rails@0.4.25-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.2.9-next.2 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.1.16-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-scaffolder-node@0.2.9-next.2 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.2.29-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.2.9-next.2 + +## @backstage/plugin-scaffolder-node@0.2.9-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.4.3 + +## @backstage/plugin-scaffolder-react@1.6.2-next.2 + +### Patch Changes + +- 5bb5240: Fixed issue for showing undefined for hidden form items +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-scaffolder-common@1.4.3 + +## @backstage/plugin-search@1.4.4-next.3 + +### Patch Changes + +- a1227cc: Wrap `/alpha` export extension elements in backwards compatibility wrapper. +- 8f5d6c1: Updates to the `/alpha` exports to match the extension input wrapping change. +- 36c94b8: Refactor of the alpha exports due to API change in how extension IDs are constructed. +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/theme@0.5.0-next.1 + - @backstage/core-compat-api@0.1.0-next.2 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/plugin-search-react@1.7.4-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-search-common@1.2.8 + +## @backstage/plugin-search-backend@1.4.8-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-openapi-utils@0.1.1-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-permission-node@0.7.19-next.2 + - @backstage/plugin-search-backend-node@1.2.12-next.2 + - @backstage/plugin-search-common@1.2.8 + +## @backstage/plugin-search-backend-module-catalog@0.1.12-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-catalog-common@1.0.18 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-search-backend-node@1.2.12-next.2 + - @backstage/plugin-search-common@1.2.8 + +## @backstage/plugin-search-backend-module-elasticsearch@1.3.11-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + - @backstage/integration-aws-node@0.1.8 + - @backstage/plugin-search-backend-node@1.2.12-next.2 + - @backstage/plugin-search-common@1.2.8 + +## @backstage/plugin-search-backend-module-explore@0.1.12-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/config@1.1.1 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-search-backend-node@1.2.12-next.2 + - @backstage/plugin-search-common@1.2.8 + +## @backstage/plugin-search-backend-module-pg@0.5.17-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + - @backstage/plugin-search-backend-node@1.2.12-next.2 + - @backstage/plugin-search-common@1.2.8 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.1-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/config@1.1.1 + - @backstage/plugin-search-backend-node@1.2.12-next.2 + - @backstage/plugin-search-common@1.2.8 + +## @backstage/plugin-search-backend-module-techdocs@0.1.12-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/plugin-catalog-common@1.0.18 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-search-backend-node@1.2.12-next.2 + - @backstage/plugin-search-common@1.2.8 + - @backstage/plugin-techdocs-node@1.11.0-next.2 + +## @backstage/plugin-search-backend-node@1.2.12-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-search-common@1.2.8 + +## @backstage/plugin-search-react@1.7.4-next.2 + +### Patch Changes + +- 36c94b8: Refactor of the alpha exports due to API change in how extension IDs are constructed. +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/theme@0.5.0-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-search-common@1.2.8 + +## @backstage/plugin-sentry@0.5.13-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + +## @backstage/plugin-shortcuts@0.3.17-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/types@1.1.1 + +## @backstage/plugin-sonarqube@0.7.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/plugin-sonarqube-react@0.1.11-next.1 + +## @backstage/plugin-sonarqube-backend@0.2.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-splunk-on-call@0.4.17-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + +## @backstage/plugin-stack-overflow@0.1.23-next.2 + +### Patch Changes + +- 36c94b8: Refactor of the alpha exports due to API change in how extension IDs are constructed. +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-search-react@1.7.4-next.2 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/plugin-home-react@0.1.6-next.2 + - @backstage/plugin-search-common@1.2.8 + +## @backstage/plugin-stack-overflow-backend@0.2.12-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.1-next.2 + - @backstage/config@1.1.1 + - @backstage/plugin-search-common@1.2.8 + +## @backstage/plugin-stackstorm@0.1.9-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-tech-insights@0.3.20-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-insights-backend@0.5.22-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + - @backstage/plugin-tech-insights-node@0.4.14-next.2 + +## @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.40-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-tech-insights-common@0.2.12 + - @backstage/plugin-tech-insights-node@0.4.14-next.2 + +## @backstage/plugin-tech-insights-node@0.4.14-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-radar@0.6.11-next.3 + +### Patch Changes + +- a1227cc: Wrap `/alpha` export extension elements in backwards compatibility wrapper. +- 36c94b8: Refactor of the alpha exports due to API change in how extension IDs are constructed. +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/theme@0.5.0-next.1 + - @backstage/core-compat-api@0.1.0-next.2 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + +## @backstage/plugin-techdocs@1.9.2-next.3 + +### Patch Changes + +- a1227cc: Wrap `/alpha` export extension elements in backwards compatibility wrapper. +- 36c94b8: Refactor of the alpha exports due to API change in how extension IDs are constructed. +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/theme@0.5.0-next.1 + - @backstage/core-compat-api@0.1.0-next.2 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/plugin-search-react@1.7.4-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/integration-react@1.1.22-next.1 + - @backstage/plugin-search-common@1.2.8 + - @backstage/plugin-techdocs-react@1.1.14-next.2 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.25-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-techdocs@1.9.2-next.3 + - @backstage/plugin-catalog@1.16.0-next.3 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/plugin-search-react@1.7.4-next.2 + - @backstage/core-app-api@1.11.2-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/integration-react@1.1.22-next.1 + - @backstage/test-utils@1.4.6-next.2 + - @backstage/plugin-techdocs-react@1.1.14-next.2 + +## @backstage/plugin-techdocs-backend@1.9.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.1.12-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/plugin-catalog-common@1.0.18 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-search-common@1.2.8 + - @backstage/plugin-techdocs-node@1.11.0-next.2 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/integration@1.8.0-next.1 + - @backstage/integration-react@1.1.22-next.1 + - @backstage/plugin-techdocs-react@1.1.14-next.2 + +## @backstage/plugin-techdocs-node@1.11.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/integration-aws-node@0.1.8 + - @backstage/plugin-search-common@1.2.8 + +## @backstage/plugin-techdocs-react@1.1.14-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/plugin-todo@0.2.32-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-todo-backend@0.3.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/backend-openapi-utils@0.1.1-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + +## @backstage/plugin-user-settings@0.7.14-next.3 + +### Patch Changes + +- a1227cc: Wrap `/alpha` export extension elements in backwards compatibility wrapper. +- 8f5d6c1: Updates to the `/alpha` exports to match the extension input wrapping change. +- 36c94b8: Refactor of the alpha exports due to API change in how extension IDs are constructed. +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/theme@0.5.0-next.1 + - @backstage/core-compat-api@0.1.0-next.2 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/core-app-api@1.11.2-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-user-settings-backend@0.2.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-vault@0.1.23-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-vault-backend@0.4.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-vault-node@0.1.1-next.2 + +## @backstage/plugin-vault-node@0.1.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.8-next.2 + +## @backstage/plugin-xcmetrics@0.2.46-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + +## example-app@0.2.90-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-app-api@0.4.0-next.2 + - @backstage/cli@0.25.0-next.2 + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-kubernetes@0.11.3-next.2 + - @backstage/plugin-lighthouse@0.4.13-next.2 + - @backstage/plugin-catalog-import@0.10.4-next.3 + - @backstage/plugin-user-settings@0.7.14-next.3 + - @backstage/plugin-tech-radar@0.6.11-next.3 + - @backstage/plugin-graphiql@0.3.1-next.3 + - @backstage/plugin-techdocs@1.9.2-next.3 + - @backstage/plugin-catalog@1.16.0-next.3 + - @backstage/plugin-search@1.4.4-next.3 + - @backstage/plugin-home@0.6.0-next.2 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/plugin-stack-overflow@0.1.23-next.2 + - @backstage/plugin-search-react@1.7.4-next.2 + - @backstage/plugin-explore@0.4.14-next.2 + - @backstage/plugin-adr@0.6.11-next.2 + - @backstage/plugin-scaffolder-react@1.6.2-next.2 + - @backstage/app-defaults@1.4.6-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-app-api@1.11.2-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/integration-react@1.1.22-next.1 + - @backstage/plugin-airbrake@0.3.28-next.2 + - @backstage/plugin-apache-airflow@0.2.18-next.2 + - @backstage/plugin-api-docs@0.10.2-next.3 + - @backstage/plugin-azure-devops@0.3.10-next.2 + - @backstage/plugin-azure-sites@0.1.17-next.2 + - @backstage/plugin-badges@0.2.52-next.2 + - @backstage/plugin-catalog-common@1.0.18 + - @backstage/plugin-catalog-graph@0.3.2-next.2 + - @backstage/plugin-catalog-unprocessed-entities@0.1.6-next.2 + - @backstage/plugin-cloudbuild@0.3.28-next.2 + - @backstage/plugin-code-coverage@0.2.21-next.2 + - @backstage/plugin-cost-insights@0.12.17-next.2 + - @backstage/plugin-devtools@0.1.7-next.2 + - @backstage/plugin-dynatrace@8.0.2-next.2 + - @backstage/plugin-entity-feedback@0.2.11-next.2 + - @backstage/plugin-gcalendar@0.3.21-next.2 + - @backstage/plugin-gcp-projects@0.3.44-next.2 + - @backstage/plugin-github-actions@0.6.9-next.2 + - @backstage/plugin-gocd@0.1.34-next.2 + - @backstage/plugin-jenkins@0.9.3-next.2 + - @backstage/plugin-kafka@0.3.28-next.2 + - @backstage/plugin-kubernetes-cluster@0.0.4-next.2 + - @backstage/plugin-linguist@0.1.13-next.2 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-microsoft-calendar@0.1.10-next.2 + - @backstage/plugin-newrelic@0.3.43-next.2 + - @backstage/plugin-newrelic-dashboard@0.3.3-next.2 + - @backstage/plugin-nomad@0.1.9-next.2 + - @backstage/plugin-octopus-deploy@0.2.10-next.2 + - @backstage/plugin-org@0.6.18-next.2 + - @backstage/plugin-pagerduty@0.7.0-next.2 + - @backstage/plugin-permission-react@0.4.18-next.1 + - @backstage/plugin-playlist@0.2.2-next.2 + - @backstage/plugin-puppetdb@0.1.11-next.2 + - @backstage/plugin-rollbar@0.4.28-next.2 + - @backstage/plugin-scaffolder@1.16.2-next.2 + - @backstage/plugin-search-common@1.2.8 + - @backstage/plugin-sentry@0.5.13-next.2 + - @backstage/plugin-shortcuts@0.3.17-next.2 + - @backstage/plugin-stackstorm@0.1.9-next.2 + - @backstage/plugin-tech-insights@0.3.20-next.2 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.3-next.2 + - @backstage/plugin-techdocs-react@1.1.14-next.2 + - @backstage/plugin-todo@0.2.32-next.2 + +## example-app-next@0.0.4-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/frontend-app-api@0.4.0-next.2 + - @backstage/cli@0.25.0-next.2 + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-kubernetes@0.11.3-next.2 + - @backstage/core-compat-api@0.1.0-next.2 + - @backstage/plugin-lighthouse@0.4.13-next.2 + - @backstage/plugin-catalog-import@0.10.4-next.3 + - @backstage/plugin-user-settings@0.7.14-next.3 + - @backstage/plugin-tech-radar@0.6.11-next.3 + - @backstage/plugin-graphiql@0.3.1-next.3 + - @backstage/plugin-techdocs@1.9.2-next.3 + - @backstage/plugin-catalog@1.16.0-next.3 + - @backstage/plugin-search@1.4.4-next.3 + - @backstage/plugin-home@0.6.0-next.2 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/plugin-search-react@1.7.4-next.2 + - @backstage/plugin-explore@0.4.14-next.2 + - @backstage/plugin-adr@0.6.11-next.2 + - @backstage/plugin-scaffolder-react@1.6.2-next.2 + - app-next-example-plugin@0.0.4-next.2 + - @backstage/app-defaults@1.4.6-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-app-api@1.11.2-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/integration-react@1.1.22-next.1 + - @backstage/plugin-airbrake@0.3.28-next.2 + - @backstage/plugin-apache-airflow@0.2.18-next.2 + - @backstage/plugin-api-docs@0.10.2-next.3 + - @backstage/plugin-azure-devops@0.3.10-next.2 + - @backstage/plugin-azure-sites@0.1.17-next.2 + - @backstage/plugin-badges@0.2.52-next.2 + - @backstage/plugin-catalog-common@1.0.18 + - @backstage/plugin-catalog-graph@0.3.2-next.2 + - @backstage/plugin-catalog-unprocessed-entities@0.1.6-next.2 + - @backstage/plugin-cloudbuild@0.3.28-next.2 + - @backstage/plugin-code-coverage@0.2.21-next.2 + - @backstage/plugin-cost-insights@0.12.17-next.2 + - @backstage/plugin-devtools@0.1.7-next.2 + - @backstage/plugin-dynatrace@8.0.2-next.2 + - @backstage/plugin-entity-feedback@0.2.11-next.2 + - @backstage/plugin-gcalendar@0.3.21-next.2 + - @backstage/plugin-gcp-projects@0.3.44-next.2 + - @backstage/plugin-github-actions@0.6.9-next.2 + - @backstage/plugin-gocd@0.1.34-next.2 + - @backstage/plugin-jenkins@0.9.3-next.2 + - @backstage/plugin-kafka@0.3.28-next.2 + - @backstage/plugin-linguist@0.1.13-next.2 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-microsoft-calendar@0.1.10-next.2 + - @backstage/plugin-newrelic@0.3.43-next.2 + - @backstage/plugin-newrelic-dashboard@0.3.3-next.2 + - @backstage/plugin-octopus-deploy@0.2.10-next.2 + - @backstage/plugin-org@0.6.18-next.2 + - @backstage/plugin-pagerduty@0.7.0-next.2 + - @backstage/plugin-permission-react@0.4.18-next.1 + - @backstage/plugin-playlist@0.2.2-next.2 + - @backstage/plugin-puppetdb@0.1.11-next.2 + - @backstage/plugin-rollbar@0.4.28-next.2 + - @backstage/plugin-scaffolder@1.16.2-next.2 + - @backstage/plugin-search-common@1.2.8 + - @backstage/plugin-sentry@0.5.13-next.2 + - @backstage/plugin-shortcuts@0.3.17-next.2 + - @backstage/plugin-stackstorm@0.1.9-next.2 + - @backstage/plugin-tech-insights@0.3.20-next.2 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.3-next.2 + - @backstage/plugin-techdocs-react@1.1.14-next.2 + - @backstage/plugin-todo@0.2.32-next.2 + +## app-next-example-plugin@0.0.4-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/core-components@0.13.9-next.2 + +## example-backend@0.2.90-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/plugin-catalog-backend@1.16.0-next.2 + - @backstage/plugin-auth-backend@0.20.1-next.2 + - @backstage/plugin-lighthouse-backend@0.4.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.5-next.2 + - @backstage/plugin-search-backend-module-elasticsearch@1.3.11-next.2 + - @backstage/plugin-catalog-backend-module-unprocessed@0.3.5-next.2 + - @backstage/plugin-search-backend-module-techdocs@0.1.12-next.2 + - @backstage/plugin-search-backend-module-catalog@0.1.12-next.2 + - @backstage/plugin-search-backend-module-explore@0.1.12-next.2 + - @backstage/plugin-search-backend-module-pg@0.5.17-next.2 + - @backstage/plugin-events-backend@0.2.17-next.2 + - example-app@0.2.90-next.3 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/integration@1.8.0-next.1 + - @backstage/plugin-adr-backend@0.4.5-next.2 + - @backstage/plugin-app-backend@0.3.56-next.2 + - @backstage/plugin-azure-devops-backend@0.5.0-next.2 + - @backstage/plugin-azure-sites-backend@0.1.18-next.2 + - @backstage/plugin-badges-backend@0.3.5-next.2 + - @backstage/plugin-code-coverage-backend@0.2.22-next.2 + - @backstage/plugin-devtools-backend@0.2.5-next.2 + - @backstage/plugin-entity-feedback-backend@0.2.5-next.2 + - @backstage/plugin-events-node@0.2.17-next.2 + - @backstage/plugin-explore-backend@0.0.18-next.2 + - @backstage/plugin-jenkins-backend@0.3.2-next.2 + - @backstage/plugin-kafka-backend@0.3.6-next.2 + - @backstage/plugin-kubernetes-backend@0.14.0-next.2 + - @backstage/plugin-linguist-backend@0.5.5-next.2 + - @backstage/plugin-nomad-backend@0.1.10-next.2 + - @backstage/plugin-permission-backend@0.5.31-next.2 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-permission-node@0.7.19-next.2 + - @backstage/plugin-playlist-backend@0.3.12-next.2 + - @backstage/plugin-proxy-backend@0.4.6-next.2 + - @backstage/plugin-rollbar-backend@0.1.53-next.2 + - @backstage/plugin-scaffolder-backend@1.19.2-next.2 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.9-next.2 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.25-next.2 + - @backstage/plugin-search-backend@1.4.8-next.2 + - @backstage/plugin-search-backend-node@1.2.12-next.2 + - @backstage/plugin-search-common@1.2.8 + - @backstage/plugin-tech-insights-backend@0.5.22-next.2 + - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.40-next.2 + - @backstage/plugin-tech-insights-node@0.4.14-next.2 + - @backstage/plugin-techdocs-backend@1.9.1-next.2 + - @backstage/plugin-todo-backend@0.3.6-next.2 + +## example-backend-next@0.0.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.16.0-next.2 + - @backstage/plugin-lighthouse-backend@0.4.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.5-next.2 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.1.5-next.2 + - @backstage/plugin-catalog-backend-module-unprocessed@0.3.5-next.2 + - @backstage/plugin-search-backend-module-techdocs@0.1.12-next.2 + - @backstage/plugin-search-backend-module-catalog@0.1.12-next.2 + - @backstage/plugin-search-backend-module-explore@0.1.12-next.2 + - @backstage/backend-defaults@0.2.8-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/plugin-adr-backend@0.4.5-next.2 + - @backstage/plugin-app-backend@0.3.56-next.2 + - @backstage/plugin-azure-devops-backend@0.5.0-next.2 + - @backstage/plugin-badges-backend@0.3.5-next.2 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.1.1-next.2 + - @backstage/plugin-catalog-backend-module-openapi@0.1.25-next.2 + - @backstage/plugin-devtools-backend@0.2.5-next.2 + - @backstage/plugin-entity-feedback-backend@0.2.5-next.2 + - @backstage/plugin-jenkins-backend@0.3.2-next.2 + - @backstage/plugin-kubernetes-backend@0.14.0-next.2 + - @backstage/plugin-linguist-backend@0.5.5-next.2 + - @backstage/plugin-nomad-backend@0.1.10-next.2 + - @backstage/plugin-permission-backend@0.5.31-next.2 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-permission-node@0.7.19-next.2 + - @backstage/plugin-playlist-backend@0.3.12-next.2 + - @backstage/plugin-proxy-backend@0.4.6-next.2 + - @backstage/plugin-scaffolder-backend@1.19.2-next.2 + - @backstage/plugin-search-backend@1.4.8-next.2 + - @backstage/plugin-search-backend-node@1.2.12-next.2 + - @backstage/plugin-sonarqube-backend@0.2.10-next.2 + - @backstage/plugin-techdocs-backend@1.9.1-next.2 + - @backstage/plugin-todo-backend@0.3.6-next.2 + +## @backstage/backend-plugin-manager@0.0.4-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.16.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/plugin-events-backend@0.2.17-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/cli-common@0.1.13 + - @backstage/cli-node@0.2.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.2.17-next.2 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-permission-node@0.7.19-next.2 + - @backstage/plugin-scaffolder-node@0.2.9-next.2 + - @backstage/plugin-search-backend-node@1.2.12-next.2 + - @backstage/plugin-search-common@1.2.8 + +## e2e-test@0.2.10-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.8-next.3 + - @backstage/cli-common@0.1.13 + - @backstage/errors@1.2.3 + +## techdocs-cli-embedded-app@0.2.89-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.25.0-next.2 + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-techdocs@1.9.2-next.3 + - @backstage/plugin-catalog@1.16.0-next.3 + - @backstage/app-defaults@1.4.6-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-app-api@1.11.2-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/integration-react@1.1.22-next.1 + - @backstage/test-utils@1.4.6-next.2 + - @backstage/plugin-techdocs-react@1.1.14-next.2 + +## @internal/plugin-todo-list@1.0.20-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + +## @internal/plugin-todo-list-backend@1.0.20-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 diff --git a/package.json b/package.json index 15c4a95953..c19dea9d3b 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "@material-ui/pickers@^3.3.10": "patch:@material-ui/pickers@npm%3A3.3.11#./.yarn/patches/@material-ui-pickers-npm-3.3.11-1c8f68ea20.patch", "@material-ui/pickers@^3.2.10": "patch:@material-ui/pickers@npm%3A3.3.11#./.yarn/patches/@material-ui-pickers-npm-3.3.11-1c8f68ea20.patch" }, - "version": "1.21.0-next.2", + "version": "1.21.0-next.3", "dependencies": { "@backstage/errors": "workspace:^", "@manypkg/get-packages": "^1.1.3", diff --git a/packages/app-defaults/CHANGELOG.md b/packages/app-defaults/CHANGELOG.md index 3326a33169..3db36e9591 100644 --- a/packages/app-defaults/CHANGELOG.md +++ b/packages/app-defaults/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/app-defaults +## 1.4.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/core-app-api@1.11.2-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/plugin-permission-react@0.4.18-next.1 + ## 1.4.6-next.1 ### Patch Changes diff --git a/packages/app-defaults/package.json b/packages/app-defaults/package.json index 4857a14492..a1301a29c5 100644 --- a/packages/app-defaults/package.json +++ b/packages/app-defaults/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/app-defaults", "description": "Provides the default wiring of a Backstage App", - "version": "1.4.6-next.1", + "version": "1.4.6-next.2", "publishConfig": { "access": "public", "main": "dist/index.esm.js", diff --git a/packages/app-next-example-plugin/CHANGELOG.md b/packages/app-next-example-plugin/CHANGELOG.md index d47b2cf2eb..9467dd00f0 100644 --- a/packages/app-next-example-plugin/CHANGELOG.md +++ b/packages/app-next-example-plugin/CHANGELOG.md @@ -1,5 +1,13 @@ # app-next-example-plugin +## 0.0.4-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/core-components@0.13.9-next.2 + ## 0.0.4-next.1 ### Patch Changes diff --git a/packages/app-next-example-plugin/package.json b/packages/app-next-example-plugin/package.json index 4e7e84dbe2..689d90e264 100644 --- a/packages/app-next-example-plugin/package.json +++ b/packages/app-next-example-plugin/package.json @@ -1,7 +1,7 @@ { "name": "app-next-example-plugin", "description": "Backstage internal example plugin", - "version": "0.0.4-next.1", + "version": "0.0.4-next.2", "publishConfig": { "access": "public", "main": "dist/index.esm.js", diff --git a/packages/app-next/CHANGELOG.md b/packages/app-next/CHANGELOG.md index ccf60e4e76..bf7b61d510 100644 --- a/packages/app-next/CHANGELOG.md +++ b/packages/app-next/CHANGELOG.md @@ -1,5 +1,81 @@ # example-app-next +## 0.0.4-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/frontend-app-api@0.4.0-next.2 + - @backstage/cli@0.25.0-next.2 + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-kubernetes@0.11.3-next.2 + - @backstage/core-compat-api@0.1.0-next.2 + - @backstage/plugin-lighthouse@0.4.13-next.2 + - @backstage/plugin-catalog-import@0.10.4-next.3 + - @backstage/plugin-user-settings@0.7.14-next.3 + - @backstage/plugin-tech-radar@0.6.11-next.3 + - @backstage/plugin-graphiql@0.3.1-next.3 + - @backstage/plugin-techdocs@1.9.2-next.3 + - @backstage/plugin-catalog@1.16.0-next.3 + - @backstage/plugin-search@1.4.4-next.3 + - @backstage/plugin-home@0.6.0-next.2 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/plugin-search-react@1.7.4-next.2 + - @backstage/plugin-explore@0.4.14-next.2 + - @backstage/plugin-adr@0.6.11-next.2 + - @backstage/plugin-scaffolder-react@1.6.2-next.2 + - app-next-example-plugin@0.0.4-next.2 + - @backstage/app-defaults@1.4.6-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-app-api@1.11.2-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/integration-react@1.1.22-next.1 + - @backstage/plugin-airbrake@0.3.28-next.2 + - @backstage/plugin-apache-airflow@0.2.18-next.2 + - @backstage/plugin-api-docs@0.10.2-next.3 + - @backstage/plugin-azure-devops@0.3.10-next.2 + - @backstage/plugin-azure-sites@0.1.17-next.2 + - @backstage/plugin-badges@0.2.52-next.2 + - @backstage/plugin-catalog-common@1.0.18 + - @backstage/plugin-catalog-graph@0.3.2-next.2 + - @backstage/plugin-catalog-unprocessed-entities@0.1.6-next.2 + - @backstage/plugin-cloudbuild@0.3.28-next.2 + - @backstage/plugin-code-coverage@0.2.21-next.2 + - @backstage/plugin-cost-insights@0.12.17-next.2 + - @backstage/plugin-devtools@0.1.7-next.2 + - @backstage/plugin-dynatrace@8.0.2-next.2 + - @backstage/plugin-entity-feedback@0.2.11-next.2 + - @backstage/plugin-gcalendar@0.3.21-next.2 + - @backstage/plugin-gcp-projects@0.3.44-next.2 + - @backstage/plugin-github-actions@0.6.9-next.2 + - @backstage/plugin-gocd@0.1.34-next.2 + - @backstage/plugin-jenkins@0.9.3-next.2 + - @backstage/plugin-kafka@0.3.28-next.2 + - @backstage/plugin-linguist@0.1.13-next.2 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-microsoft-calendar@0.1.10-next.2 + - @backstage/plugin-newrelic@0.3.43-next.2 + - @backstage/plugin-newrelic-dashboard@0.3.3-next.2 + - @backstage/plugin-octopus-deploy@0.2.10-next.2 + - @backstage/plugin-org@0.6.18-next.2 + - @backstage/plugin-pagerduty@0.7.0-next.2 + - @backstage/plugin-permission-react@0.4.18-next.1 + - @backstage/plugin-playlist@0.2.2-next.2 + - @backstage/plugin-puppetdb@0.1.11-next.2 + - @backstage/plugin-rollbar@0.4.28-next.2 + - @backstage/plugin-scaffolder@1.16.2-next.2 + - @backstage/plugin-search-common@1.2.8 + - @backstage/plugin-sentry@0.5.13-next.2 + - @backstage/plugin-shortcuts@0.3.17-next.2 + - @backstage/plugin-stackstorm@0.1.9-next.2 + - @backstage/plugin-tech-insights@0.3.20-next.2 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.3-next.2 + - @backstage/plugin-techdocs-react@1.1.14-next.2 + - @backstage/plugin-todo@0.2.32-next.2 + ## 0.0.4-next.2 ### Patch Changes diff --git a/packages/app-next/package.json b/packages/app-next/package.json index 8e441b0e4a..276ae4e527 100644 --- a/packages/app-next/package.json +++ b/packages/app-next/package.json @@ -1,6 +1,6 @@ { "name": "example-app-next", - "version": "0.0.4-next.2", + "version": "0.0.4-next.3", "private": true, "backstage": { "role": "frontend" diff --git a/packages/app/CHANGELOG.md b/packages/app/CHANGELOG.md index 546a7918d7..159468d4ef 100644 --- a/packages/app/CHANGELOG.md +++ b/packages/app/CHANGELOG.md @@ -1,5 +1,81 @@ # example-app +## 0.2.90-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-app-api@0.4.0-next.2 + - @backstage/cli@0.25.0-next.2 + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-kubernetes@0.11.3-next.2 + - @backstage/plugin-lighthouse@0.4.13-next.2 + - @backstage/plugin-catalog-import@0.10.4-next.3 + - @backstage/plugin-user-settings@0.7.14-next.3 + - @backstage/plugin-tech-radar@0.6.11-next.3 + - @backstage/plugin-graphiql@0.3.1-next.3 + - @backstage/plugin-techdocs@1.9.2-next.3 + - @backstage/plugin-catalog@1.16.0-next.3 + - @backstage/plugin-search@1.4.4-next.3 + - @backstage/plugin-home@0.6.0-next.2 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/plugin-stack-overflow@0.1.23-next.2 + - @backstage/plugin-search-react@1.7.4-next.2 + - @backstage/plugin-explore@0.4.14-next.2 + - @backstage/plugin-adr@0.6.11-next.2 + - @backstage/plugin-scaffolder-react@1.6.2-next.2 + - @backstage/app-defaults@1.4.6-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-app-api@1.11.2-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/integration-react@1.1.22-next.1 + - @backstage/plugin-airbrake@0.3.28-next.2 + - @backstage/plugin-apache-airflow@0.2.18-next.2 + - @backstage/plugin-api-docs@0.10.2-next.3 + - @backstage/plugin-azure-devops@0.3.10-next.2 + - @backstage/plugin-azure-sites@0.1.17-next.2 + - @backstage/plugin-badges@0.2.52-next.2 + - @backstage/plugin-catalog-common@1.0.18 + - @backstage/plugin-catalog-graph@0.3.2-next.2 + - @backstage/plugin-catalog-unprocessed-entities@0.1.6-next.2 + - @backstage/plugin-cloudbuild@0.3.28-next.2 + - @backstage/plugin-code-coverage@0.2.21-next.2 + - @backstage/plugin-cost-insights@0.12.17-next.2 + - @backstage/plugin-devtools@0.1.7-next.2 + - @backstage/plugin-dynatrace@8.0.2-next.2 + - @backstage/plugin-entity-feedback@0.2.11-next.2 + - @backstage/plugin-gcalendar@0.3.21-next.2 + - @backstage/plugin-gcp-projects@0.3.44-next.2 + - @backstage/plugin-github-actions@0.6.9-next.2 + - @backstage/plugin-gocd@0.1.34-next.2 + - @backstage/plugin-jenkins@0.9.3-next.2 + - @backstage/plugin-kafka@0.3.28-next.2 + - @backstage/plugin-kubernetes-cluster@0.0.4-next.2 + - @backstage/plugin-linguist@0.1.13-next.2 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-microsoft-calendar@0.1.10-next.2 + - @backstage/plugin-newrelic@0.3.43-next.2 + - @backstage/plugin-newrelic-dashboard@0.3.3-next.2 + - @backstage/plugin-nomad@0.1.9-next.2 + - @backstage/plugin-octopus-deploy@0.2.10-next.2 + - @backstage/plugin-org@0.6.18-next.2 + - @backstage/plugin-pagerduty@0.7.0-next.2 + - @backstage/plugin-permission-react@0.4.18-next.1 + - @backstage/plugin-playlist@0.2.2-next.2 + - @backstage/plugin-puppetdb@0.1.11-next.2 + - @backstage/plugin-rollbar@0.4.28-next.2 + - @backstage/plugin-scaffolder@1.16.2-next.2 + - @backstage/plugin-search-common@1.2.8 + - @backstage/plugin-sentry@0.5.13-next.2 + - @backstage/plugin-shortcuts@0.3.17-next.2 + - @backstage/plugin-stackstorm@0.1.9-next.2 + - @backstage/plugin-tech-insights@0.3.20-next.2 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.3-next.2 + - @backstage/plugin-techdocs-react@1.1.14-next.2 + - @backstage/plugin-todo@0.2.32-next.2 + ## 0.2.90-next.2 ### Patch Changes diff --git a/packages/app/package.json b/packages/app/package.json index e47388a7e1..7d275ee990 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "example-app", - "version": "0.2.90-next.2", + "version": "0.2.90-next.3", "private": true, "backstage": { "role": "frontend" diff --git a/packages/backend-app-api/CHANGELOG.md b/packages/backend-app-api/CHANGELOG.md index e3a25d9514..39110bfa4d 100644 --- a/packages/backend-app-api/CHANGELOG.md +++ b/packages/backend-app-api/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/backend-app-api +## 0.5.9-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.6.0-next.0 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/cli-common@0.1.13 + - @backstage/cli-node@0.2.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-node@0.7.19-next.2 + ## 0.5.9-next.1 ### Patch Changes diff --git a/packages/backend-app-api/package.json b/packages/backend-app-api/package.json index bf1269d0c9..acd97ab544 100644 --- a/packages/backend-app-api/package.json +++ b/packages/backend-app-api/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-app-api", "description": "Core API used by Backstage backend apps", - "version": "0.5.9-next.1", + "version": "0.5.9-next.2", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-common/CHANGELOG.md b/packages/backend-common/CHANGELOG.md index dbe198bdb8..d4cce4ee08 100644 --- a/packages/backend-common/CHANGELOG.md +++ b/packages/backend-common/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/backend-common +## 0.20.0-next.2 + +### Patch Changes + +- bc67498: Updated dependency `archiver` to `^6.0.0`. + Updated dependency `@types/archiver` to `^6.0.0`. +- Updated dependencies + - @backstage/config-loader@1.6.0-next.0 + - @backstage/backend-app-api@0.5.9-next.2 + - @backstage/backend-dev-utils@0.1.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/integration-aws-node@0.1.8 + - @backstage/types@1.1.1 + ## 0.20.0-next.1 ### Patch Changes diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json index 357c929e6c..1f68db8ba8 100644 --- a/packages/backend-common/package.json +++ b/packages/backend-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-common", "description": "Common functionality library for Backstage backends", - "version": "0.20.0-next.1", + "version": "0.20.0-next.2", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-defaults/CHANGELOG.md b/packages/backend-defaults/CHANGELOG.md index 5f2063890a..7a1604939c 100644 --- a/packages/backend-defaults/CHANGELOG.md +++ b/packages/backend-defaults/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/backend-defaults +## 0.2.8-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-app-api@0.5.9-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + ## 0.2.8-next.1 ### Patch Changes diff --git a/packages/backend-defaults/package.json b/packages/backend-defaults/package.json index d9ff1ea302..d7d8d59cb8 100644 --- a/packages/backend-defaults/package.json +++ b/packages/backend-defaults/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-defaults", "description": "Backend defaults used by Backstage backend apps", - "version": "0.2.8-next.1", + "version": "0.2.8-next.2", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-next/CHANGELOG.md b/packages/backend-next/CHANGELOG.md index c1bfc21fba..e8af725114 100644 --- a/packages/backend-next/CHANGELOG.md +++ b/packages/backend-next/CHANGELOG.md @@ -1,5 +1,46 @@ # example-backend-next +## 0.0.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.16.0-next.2 + - @backstage/plugin-lighthouse-backend@0.4.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.5-next.2 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.1.5-next.2 + - @backstage/plugin-catalog-backend-module-unprocessed@0.3.5-next.2 + - @backstage/plugin-search-backend-module-techdocs@0.1.12-next.2 + - @backstage/plugin-search-backend-module-catalog@0.1.12-next.2 + - @backstage/plugin-search-backend-module-explore@0.1.12-next.2 + - @backstage/backend-defaults@0.2.8-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/plugin-adr-backend@0.4.5-next.2 + - @backstage/plugin-app-backend@0.3.56-next.2 + - @backstage/plugin-azure-devops-backend@0.5.0-next.2 + - @backstage/plugin-badges-backend@0.3.5-next.2 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.1.1-next.2 + - @backstage/plugin-catalog-backend-module-openapi@0.1.25-next.2 + - @backstage/plugin-devtools-backend@0.2.5-next.2 + - @backstage/plugin-entity-feedback-backend@0.2.5-next.2 + - @backstage/plugin-jenkins-backend@0.3.2-next.2 + - @backstage/plugin-kubernetes-backend@0.14.0-next.2 + - @backstage/plugin-linguist-backend@0.5.5-next.2 + - @backstage/plugin-nomad-backend@0.1.10-next.2 + - @backstage/plugin-permission-backend@0.5.31-next.2 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-permission-node@0.7.19-next.2 + - @backstage/plugin-playlist-backend@0.3.12-next.2 + - @backstage/plugin-proxy-backend@0.4.6-next.2 + - @backstage/plugin-scaffolder-backend@1.19.2-next.2 + - @backstage/plugin-search-backend@1.4.8-next.2 + - @backstage/plugin-search-backend-node@1.2.12-next.2 + - @backstage/plugin-sonarqube-backend@0.2.10-next.2 + - @backstage/plugin-techdocs-backend@1.9.1-next.2 + - @backstage/plugin-todo-backend@0.3.6-next.2 + ## 0.0.18-next.1 ### Patch Changes diff --git a/packages/backend-next/package.json b/packages/backend-next/package.json index fd7845252d..a52cd949e0 100644 --- a/packages/backend-next/package.json +++ b/packages/backend-next/package.json @@ -1,6 +1,6 @@ { "name": "example-backend-next", - "version": "0.0.18-next.1", + "version": "0.0.18-next.2", "main": "dist/index.cjs.js", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/backend-openapi-utils/CHANGELOG.md b/packages/backend-openapi-utils/CHANGELOG.md index 6df79cdcd8..00fe5bfa8f 100644 --- a/packages/backend-openapi-utils/CHANGELOG.md +++ b/packages/backend-openapi-utils/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/backend-openapi-utils +## 0.1.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + ## 0.1.1-next.1 ### Patch Changes diff --git a/packages/backend-openapi-utils/package.json b/packages/backend-openapi-utils/package.json index d97638c05f..05fcf3e6d6 100644 --- a/packages/backend-openapi-utils/package.json +++ b/packages/backend-openapi-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-openapi-utils", "description": "OpenAPI typescript support.", - "version": "0.1.1-next.1", + "version": "0.1.1-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/backend-plugin-api/CHANGELOG.md b/packages/backend-plugin-api/CHANGELOG.md index 9c3f730912..487799c4dc 100644 --- a/packages/backend-plugin-api/CHANGELOG.md +++ b/packages/backend-plugin-api/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/backend-plugin-api +## 0.6.8-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.10 + ## 0.6.8-next.1 ### Patch Changes diff --git a/packages/backend-plugin-api/package.json b/packages/backend-plugin-api/package.json index bf7cee4e1b..c335d1f0a2 100644 --- a/packages/backend-plugin-api/package.json +++ b/packages/backend-plugin-api/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-plugin-api", "description": "Core API used by Backstage backend plugins", - "version": "0.6.8-next.1", + "version": "0.6.8-next.2", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-plugin-manager/CHANGELOG.md b/packages/backend-plugin-manager/CHANGELOG.md index e4481c8bac..2f846adeaa 100644 --- a/packages/backend-plugin-manager/CHANGELOG.md +++ b/packages/backend-plugin-manager/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/backend-plugin-manager +## 0.0.4-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.16.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/plugin-events-backend@0.2.17-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/cli-common@0.1.13 + - @backstage/cli-node@0.2.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.2.17-next.2 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-permission-node@0.7.19-next.2 + - @backstage/plugin-scaffolder-node@0.2.9-next.2 + - @backstage/plugin-search-backend-node@1.2.12-next.2 + - @backstage/plugin-search-common@1.2.8 + ## 0.0.4-next.1 ### Patch Changes diff --git a/packages/backend-plugin-manager/package.json b/packages/backend-plugin-manager/package.json index 7b3a57cc7b..3e91feb9ba 100644 --- a/packages/backend-plugin-manager/package.json +++ b/packages/backend-plugin-manager/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-plugin-manager", "description": "Backstage plugin management backend", - "version": "0.0.4-next.1", + "version": "0.0.4-next.2", "private": true, "main": "src/index.ts", "types": "src/index.ts", diff --git a/packages/backend-tasks/CHANGELOG.md b/packages/backend-tasks/CHANGELOG.md index c25edab02d..8360c78337 100644 --- a/packages/backend-tasks/CHANGELOG.md +++ b/packages/backend-tasks/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/backend-tasks +## 0.5.13-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + ## 0.5.13-next.1 ### Patch Changes diff --git a/packages/backend-tasks/package.json b/packages/backend-tasks/package.json index f577380a7c..f1ac622864 100644 --- a/packages/backend-tasks/package.json +++ b/packages/backend-tasks/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-tasks", "description": "Common distributed task management library for Backstage backends", - "version": "0.5.13-next.1", + "version": "0.5.13-next.2", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-test-utils/CHANGELOG.md b/packages/backend-test-utils/CHANGELOG.md index cd9428b8a0..697572d50c 100644 --- a/packages/backend-test-utils/CHANGELOG.md +++ b/packages/backend-test-utils/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/backend-test-utils +## 0.2.9-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-app-api@0.5.9-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + ## 0.2.9-next.1 ### Patch Changes diff --git a/packages/backend-test-utils/package.json b/packages/backend-test-utils/package.json index 390bb99954..e1983924ab 100644 --- a/packages/backend-test-utils/package.json +++ b/packages/backend-test-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-test-utils", "description": "Test helpers library for Backstage backends", - "version": "0.2.9-next.1", + "version": "0.2.9-next.2", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend/CHANGELOG.md b/packages/backend/CHANGELOG.md index f3a446b211..272c3f17ee 100644 --- a/packages/backend/CHANGELOG.md +++ b/packages/backend/CHANGELOG.md @@ -1,5 +1,63 @@ # example-backend +## 0.2.90-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/plugin-catalog-backend@1.16.0-next.2 + - @backstage/plugin-auth-backend@0.20.1-next.2 + - @backstage/plugin-lighthouse-backend@0.4.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.5-next.2 + - @backstage/plugin-search-backend-module-elasticsearch@1.3.11-next.2 + - @backstage/plugin-catalog-backend-module-unprocessed@0.3.5-next.2 + - @backstage/plugin-search-backend-module-techdocs@0.1.12-next.2 + - @backstage/plugin-search-backend-module-catalog@0.1.12-next.2 + - @backstage/plugin-search-backend-module-explore@0.1.12-next.2 + - @backstage/plugin-search-backend-module-pg@0.5.17-next.2 + - @backstage/plugin-events-backend@0.2.17-next.2 + - example-app@0.2.90-next.3 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/integration@1.8.0-next.1 + - @backstage/plugin-adr-backend@0.4.5-next.2 + - @backstage/plugin-app-backend@0.3.56-next.2 + - @backstage/plugin-azure-devops-backend@0.5.0-next.2 + - @backstage/plugin-azure-sites-backend@0.1.18-next.2 + - @backstage/plugin-badges-backend@0.3.5-next.2 + - @backstage/plugin-code-coverage-backend@0.2.22-next.2 + - @backstage/plugin-devtools-backend@0.2.5-next.2 + - @backstage/plugin-entity-feedback-backend@0.2.5-next.2 + - @backstage/plugin-events-node@0.2.17-next.2 + - @backstage/plugin-explore-backend@0.0.18-next.2 + - @backstage/plugin-jenkins-backend@0.3.2-next.2 + - @backstage/plugin-kafka-backend@0.3.6-next.2 + - @backstage/plugin-kubernetes-backend@0.14.0-next.2 + - @backstage/plugin-linguist-backend@0.5.5-next.2 + - @backstage/plugin-nomad-backend@0.1.10-next.2 + - @backstage/plugin-permission-backend@0.5.31-next.2 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-permission-node@0.7.19-next.2 + - @backstage/plugin-playlist-backend@0.3.12-next.2 + - @backstage/plugin-proxy-backend@0.4.6-next.2 + - @backstage/plugin-rollbar-backend@0.1.53-next.2 + - @backstage/plugin-scaffolder-backend@1.19.2-next.2 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.9-next.2 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.25-next.2 + - @backstage/plugin-search-backend@1.4.8-next.2 + - @backstage/plugin-search-backend-node@1.2.12-next.2 + - @backstage/plugin-search-common@1.2.8 + - @backstage/plugin-tech-insights-backend@0.5.22-next.2 + - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.40-next.2 + - @backstage/plugin-tech-insights-node@0.4.14-next.2 + - @backstage/plugin-techdocs-backend@1.9.1-next.2 + - @backstage/plugin-todo-backend@0.3.6-next.2 + ## 0.2.90-next.1 ### Patch Changes diff --git a/packages/backend/package.json b/packages/backend/package.json index f57897f163..fe072cf11a 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -1,6 +1,6 @@ { "name": "example-backend", - "version": "0.2.90-next.1", + "version": "0.2.90-next.2", "main": "dist/index.cjs.js", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/catalog-client/CHANGELOG.md b/packages/catalog-client/CHANGELOG.md index b7517e5734..d81062fd03 100644 --- a/packages/catalog-client/CHANGELOG.md +++ b/packages/catalog-client/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/catalog-client +## 1.5.0-next.1 + +### Patch Changes + +- 82fa88b: Fixes a bug where some query parameters were double URL encoded. +- Updated dependencies + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + ## 1.5.0-next.0 ### Minor Changes diff --git a/packages/catalog-client/package.json b/packages/catalog-client/package.json index 2be5fbea43..24e4f3f4c7 100644 --- a/packages/catalog-client/package.json +++ b/packages/catalog-client/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/catalog-client", "description": "An isomorphic client for the catalog backend", - "version": "1.5.0-next.0", + "version": "1.5.0-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index acee7fd45c..5b554ad74f 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/cli +## 0.25.0-next.2 + +### Patch Changes + +- 32018ff: Enable the `tsx` loader to work on Node 18.19 and up +- a3edc18: Updated dependency `vite-plugin-node-polyfills` to `^0.17.0`. +- 627554e: Updated dependency `@rollup/plugin-node-resolve` to `^15.0.0`. +- c07cee5: Updated dependency `@rollup/plugin-json` to `^6.0.0`. +- 2565cc8: Updated dependency `@rollup/plugin-commonjs` to `^25.0.0`. +- Updated dependencies + - @backstage/config-loader@1.6.0-next.0 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/cli-node@0.2.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/eslint-plugin@0.1.4-next.0 + - @backstage/integration@1.8.0-next.1 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + ## 0.25.0-next.1 ### Minor Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index e16dfa81a3..84f75c5873 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/cli", "description": "CLI for developing Backstage plugins and apps", - "version": "0.25.0-next.1", + "version": "0.25.0-next.2", "publishConfig": { "access": "public" }, diff --git a/packages/config-loader/CHANGELOG.md b/packages/config-loader/CHANGELOG.md index 169e2e45df..d5526dd62e 100644 --- a/packages/config-loader/CHANGELOG.md +++ b/packages/config-loader/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/config-loader +## 1.6.0-next.0 + +### Minor Changes + +- 24f5a85: Add "path" to `TransformFunc` context + +### Patch Changes + +- Updated dependencies + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + ## 1.5.3 ### Patch Changes diff --git a/packages/config-loader/package.json b/packages/config-loader/package.json index 8a41d7548f..e908afa6a1 100644 --- a/packages/config-loader/package.json +++ b/packages/config-loader/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/config-loader", "description": "Config loading functionality used by Backstage backend, and CLI", - "version": "1.5.3", + "version": "1.6.0-next.0", "publishConfig": { "access": "public", "main": "dist/index.cjs.js", diff --git a/packages/core-compat-api/CHANGELOG.md b/packages/core-compat-api/CHANGELOG.md index 1be69b6986..cd069b966f 100644 --- a/packages/core-compat-api/CHANGELOG.md +++ b/packages/core-compat-api/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/core-compat-api +## 0.1.0-next.2 + +### Minor Changes + +- cf5cc4c: Discover plugins and routes recursively beneath the root routes in `collectLecacyRoutes` + +### Patch Changes + +- 8226442: Added `compatWrapper`, which can be used to wrap any React element to provide bi-directional interoperability between the `@backstage/core-*-api` and `@backstage/frontend-*-api` APIs. +- 8f5d6c1: Updates to match the new extension input wrapping. +- b7adf24: Delete alpha DI compatibility helper for components, migrating components should be simple without a helper. +- 046e443: Updates for compatibility with the new extension IDs. +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/core-app-api@1.11.2-next.1 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/version-bridge@1.0.7 + ## 0.0.1-next.1 ### Patch Changes diff --git a/packages/core-compat-api/package.json b/packages/core-compat-api/package.json index dd602f5380..b2ee3869d3 100644 --- a/packages/core-compat-api/package.json +++ b/packages/core-compat-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/core-compat-api", - "version": "0.0.1-next.1", + "version": "0.1.0-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/core-components/CHANGELOG.md b/packages/core-components/CHANGELOG.md index 6a319b1add..4702443de1 100644 --- a/packages/core-components/CHANGELOG.md +++ b/packages/core-components/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/core-components +## 0.13.9-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/config@1.1.1 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/version-bridge@1.0.7 + ## 0.13.9-next.1 ### Patch Changes diff --git a/packages/core-components/package.json b/packages/core-components/package.json index 19bcb306cc..e657e50b9d 100644 --- a/packages/core-components/package.json +++ b/packages/core-components/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core-components", "description": "Core components used by Backstage plugins and apps", - "version": "0.13.9-next.1", + "version": "0.13.9-next.2", "publishConfig": { "access": "public" }, diff --git a/packages/create-app/CHANGELOG.md b/packages/create-app/CHANGELOG.md index 9d7ccf5dce..5407afcbe8 100644 --- a/packages/create-app/CHANGELOG.md +++ b/packages/create-app/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/create-app +## 0.5.8-next.3 + +### Patch Changes + +- a96c2d4: Include the `` for group entities by default +- Updated dependencies + - @backstage/cli-common@0.1.13 + ## 0.5.8-next.2 ### Patch Changes diff --git a/packages/create-app/package.json b/packages/create-app/package.json index 06fb467244..c4deda095f 100644 --- a/packages/create-app/package.json +++ b/packages/create-app/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/create-app", "description": "A CLI that helps you create your own Backstage app", - "version": "0.5.8-next.2", + "version": "0.5.8-next.3", "publishConfig": { "access": "public" }, diff --git a/packages/dev-utils/CHANGELOG.md b/packages/dev-utils/CHANGELOG.md index 49c5a7785d..bcb9033618 100644 --- a/packages/dev-utils/CHANGELOG.md +++ b/packages/dev-utils/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/dev-utils +## 1.0.25-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/app-defaults@1.4.6-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-app-api@1.11.2-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/integration-react@1.1.22-next.1 + ## 1.0.25-next.1 ### Patch Changes diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json index d7ca26d64f..914dccf0a5 100644 --- a/packages/dev-utils/package.json +++ b/packages/dev-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/dev-utils", "description": "Utilities for developing Backstage plugins.", - "version": "1.0.25-next.1", + "version": "1.0.25-next.2", "publishConfig": { "access": "public", "main": "dist/index.esm.js", diff --git a/packages/e2e-test/CHANGELOG.md b/packages/e2e-test/CHANGELOG.md index 6b39139bac..f412da8738 100644 --- a/packages/e2e-test/CHANGELOG.md +++ b/packages/e2e-test/CHANGELOG.md @@ -1,5 +1,14 @@ # e2e-test +## 0.2.10-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.8-next.3 + - @backstage/cli-common@0.1.13 + - @backstage/errors@1.2.3 + ## 0.2.10-next.2 ### Patch Changes diff --git a/packages/e2e-test/package.json b/packages/e2e-test/package.json index 9c78471d5c..c4ea45fb91 100644 --- a/packages/e2e-test/package.json +++ b/packages/e2e-test/package.json @@ -1,7 +1,7 @@ { "name": "e2e-test", "description": "E2E test for verifying Backstage packages", - "version": "0.2.10-next.2", + "version": "0.2.10-next.3", "private": true, "backstage": { "role": "cli" diff --git a/packages/frontend-app-api/CHANGELOG.md b/packages/frontend-app-api/CHANGELOG.md index 216360658c..5867ae9ab5 100644 --- a/packages/frontend-app-api/CHANGELOG.md +++ b/packages/frontend-app-api/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/frontend-app-api +## 0.4.0-next.2 + +### Minor Changes + +- ea06590: The app no longer provides the `AppContext` from `@backstage/core-plugin-api`. Components that require this context to be available should use the `compatWrapper` helper from `@backstage/core-compat-api`. + +### Patch Changes + +- aeb8008: Add support for translation extensions. +- b7adf24: Use the new plugin type for error boundary components. +- 8f5d6c1: Updates to match the new extension input wrapping. +- cb4197a: Forward ` node`` instead of `extensionId` to resolved extension inputs. +- 8837a96: Updates to match the introduction of `ExtensionDefinition` and new extension ID naming patterns. +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/theme@0.5.0-next.1 + - @backstage/config@1.1.1 + - @backstage/core-app-api@1.11.2-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + ## 0.4.0-next.1 ### Minor Changes diff --git a/packages/frontend-app-api/package.json b/packages/frontend-app-api/package.json index 5a179ef9f0..64c1b9defc 100644 --- a/packages/frontend-app-api/package.json +++ b/packages/frontend-app-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/frontend-app-api", - "version": "0.4.0-next.1", + "version": "0.4.0-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/frontend-plugin-api/CHANGELOG.md b/packages/frontend-plugin-api/CHANGELOG.md index 74c9e784ee..2187b17aab 100644 --- a/packages/frontend-plugin-api/CHANGELOG.md +++ b/packages/frontend-plugin-api/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/frontend-plugin-api +## 0.4.0-next.2 + +### Minor Changes + +- 8f5d6c1: Extension inputs are now wrapped into an additional object when passed to the extension factory, with the previous values being available at the `output` property. The `ExtensionInputValues` type has also been replaced by `ResolvedExtensionInputs`. +- 8837a96: **BREAKING**: This version changes how extensions are created and how their IDs are determined. The `createExtension` function now accepts `kind`, `namespace` and `name` instead of `id`. All of the new options are optional, and are used to construct the final extension ID. By convention extension creators should set the `kind` to match their own name, for example `createNavItemExtension` sets the kind `nav-item`. + + The `createExtension` function as well as all extension creators now also return an `ExtensionDefinition` rather than an `Extension`, which in turn needs to be passed to `createPlugin` or `createExtensionOverrides` to be used. + +### Patch Changes + +- b7adf24: Update alpha component ref type to be more specific than any, delete boot page component and use new plugin type for error boundary component extensions. +- 73246ec: Added translation APIs as well as `createTranslationExtension`. +- cb4197a: Forward ` node`` instead of `extensionId` to resolved extension inputs. +- Updated dependencies + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + ## 0.4.0-next.1 ### Minor Changes diff --git a/packages/frontend-plugin-api/package.json b/packages/frontend-plugin-api/package.json index 4137aaabc6..813351a6a0 100644 --- a/packages/frontend-plugin-api/package.json +++ b/packages/frontend-plugin-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/frontend-plugin-api", - "version": "0.4.0-next.1", + "version": "0.4.0-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/frontend-test-utils/CHANGELOG.md b/packages/frontend-test-utils/CHANGELOG.md index b25a5a7c38..a141d85d90 100644 --- a/packages/frontend-test-utils/CHANGELOG.md +++ b/packages/frontend-test-utils/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/frontend-test-utils +## 0.1.0-next.2 + +### Patch Changes + +- 818eea4: Updates for compatibility with the new extension IDs. +- b9aa6e4: Migrate `renderInTestApp` to `@backstage/frontend-test-utils` for testing individual React components in an app. +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/frontend-app-api@0.4.0-next.2 + - @backstage/test-utils@1.4.6-next.2 + - @backstage/types@1.1.1 + ## 0.1.0-next.1 ### Patch Changes diff --git a/packages/frontend-test-utils/package.json b/packages/frontend-test-utils/package.json index 93e27869fb..9fba262c21 100644 --- a/packages/frontend-test-utils/package.json +++ b/packages/frontend-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/frontend-test-utils", - "version": "0.1.0-next.1", + "version": "0.1.0-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/repo-tools/CHANGELOG.md b/packages/repo-tools/CHANGELOG.md index 0a0802d87e..d416aa11b4 100644 --- a/packages/repo-tools/CHANGELOG.md +++ b/packages/repo-tools/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/repo-tools +## 0.5.0-next.1 + +### Patch Changes + +- f909e9d: Includes templates in @backstage/repo-tools package and use them in the CLI +- da3c4db: Updates the `schema openapi generate-client` command to export all generated types from the generated directory. +- 7959f23: The `api-reports` command now checks for api report files that no longer apply. + If it finds such files, it's treated basically the same as report errors do, and + the check fails. + + For example, if you had an `api-report-alpha.md` but then removed the alpha + export, the reports generator would now report that this file needs to be + deleted. + +- f49e237: Fixed a bug where `schema openapi init` created an invalid test command. +- f91be2c: Updated dependency `@stoplight/types` to `^14.0.0`. +- 45bfb20: Execute `openapi-generator-cli` from `@backstage/repo-tools` directory to force it to use our openapitools.json config file. +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/cli-node@0.2.0 + - @backstage/errors@1.2.3 + ## 0.5.0-next.0 ### Minor Changes diff --git a/packages/repo-tools/package.json b/packages/repo-tools/package.json index 7a7e56d68c..d0c00f3f9a 100644 --- a/packages/repo-tools/package.json +++ b/packages/repo-tools/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/repo-tools", "description": "CLI for Backstage repo tooling ", - "version": "0.5.0-next.0", + "version": "0.5.0-next.1", "publishConfig": { "access": "public" }, diff --git a/packages/techdocs-cli-embedded-app/CHANGELOG.md b/packages/techdocs-cli-embedded-app/CHANGELOG.md index 135f13d075..a7a804b74e 100644 --- a/packages/techdocs-cli-embedded-app/CHANGELOG.md +++ b/packages/techdocs-cli-embedded-app/CHANGELOG.md @@ -1,5 +1,24 @@ # techdocs-cli-embedded-app +## 0.2.89-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.25.0-next.2 + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-techdocs@1.9.2-next.3 + - @backstage/plugin-catalog@1.16.0-next.3 + - @backstage/app-defaults@1.4.6-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-app-api@1.11.2-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/integration-react@1.1.22-next.1 + - @backstage/test-utils@1.4.6-next.2 + - @backstage/plugin-techdocs-react@1.1.14-next.2 + ## 0.2.89-next.2 ### Patch Changes diff --git a/packages/techdocs-cli-embedded-app/package.json b/packages/techdocs-cli-embedded-app/package.json index f3e5485658..d487da2722 100644 --- a/packages/techdocs-cli-embedded-app/package.json +++ b/packages/techdocs-cli-embedded-app/package.json @@ -1,6 +1,6 @@ { "name": "techdocs-cli-embedded-app", - "version": "0.2.89-next.2", + "version": "0.2.89-next.3", "private": true, "backstage": { "role": "frontend" diff --git a/packages/techdocs-cli/CHANGELOG.md b/packages/techdocs-cli/CHANGELOG.md index 8769bd0c93..5e82b98a3f 100644 --- a/packages/techdocs-cli/CHANGELOG.md +++ b/packages/techdocs-cli/CHANGELOG.md @@ -1,5 +1,16 @@ # @techdocs/cli +## 1.8.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/plugin-techdocs-node@1.11.0-next.2 + ## 1.8.0-next.1 ### Minor Changes diff --git a/packages/techdocs-cli/package.json b/packages/techdocs-cli/package.json index 94f9c159ee..0e0d4c3a04 100644 --- a/packages/techdocs-cli/package.json +++ b/packages/techdocs-cli/package.json @@ -1,7 +1,7 @@ { "name": "@techdocs/cli", "description": "Utility CLI for managing TechDocs sites in Backstage.", - "version": "1.8.0-next.1", + "version": "1.8.0-next.2", "publishConfig": { "access": "public" }, diff --git a/packages/test-utils/CHANGELOG.md b/packages/test-utils/CHANGELOG.md index 9a18091f6e..476c3b5ad8 100644 --- a/packages/test-utils/CHANGELOG.md +++ b/packages/test-utils/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/test-utils +## 1.4.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/config@1.1.1 + - @backstage/core-app-api@1.11.2-next.1 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-permission-react@0.4.18-next.1 + ## 1.4.6-next.1 ### Patch Changes diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index ec48141e99..e2632227e7 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/test-utils", "description": "Utilities to test Backstage plugins and apps.", - "version": "1.4.6-next.1", + "version": "1.4.6-next.2", "publishConfig": { "access": "public" }, diff --git a/packages/theme/CHANGELOG.md b/packages/theme/CHANGELOG.md index e1ee5fe11f..808c899d43 100644 --- a/packages/theme/CHANGELOG.md +++ b/packages/theme/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/theme +## 0.5.0-next.1 + +### Patch Changes + +- cd0dd4c: Align Material UI v5 `Paper` component background color in dark mode to v4. + ## 0.5.0-next.0 ### Minor Changes diff --git a/packages/theme/package.json b/packages/theme/package.json index ad70198cf8..ac7d418ef7 100644 --- a/packages/theme/package.json +++ b/packages/theme/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/theme", "description": "material-ui theme for use with Backstage.", - "version": "0.5.0-next.0", + "version": "0.5.0-next.1", "publishConfig": { "access": "public", "main": "dist/index.esm.js", diff --git a/plugins/adr-backend/CHANGELOG.md b/plugins/adr-backend/CHANGELOG.md index 8be4a06ac9..d55efec464 100644 --- a/plugins/adr-backend/CHANGELOG.md +++ b/plugins/adr-backend/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-adr-backend +## 0.4.5-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/plugin-adr-common@0.2.18-next.1 + - @backstage/plugin-search-common@1.2.8 + ## 0.4.5-next.1 ### Patch Changes diff --git a/plugins/adr-backend/package.json b/plugins/adr-backend/package.json index c758ad68ed..03f469462a 100644 --- a/plugins/adr-backend/package.json +++ b/plugins/adr-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-adr-backend", - "version": "0.4.5-next.1", + "version": "0.4.5-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/adr/CHANGELOG.md b/plugins/adr/CHANGELOG.md index 92390fdbb8..96af85f974 100644 --- a/plugins/adr/CHANGELOG.md +++ b/plugins/adr/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-adr +## 0.6.11-next.2 + +### Patch Changes + +- 36c94b8: Refactor of the alpha exports due to API change in how extension IDs are constructed. +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/plugin-search-react@1.7.4-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/integration-react@1.1.22-next.1 + - @backstage/plugin-adr-common@0.2.18-next.1 + - @backstage/plugin-search-common@1.2.8 + ## 0.6.11-next.1 ### Patch Changes diff --git a/plugins/adr/package.json b/plugins/adr/package.json index 54d4bc7b8c..61cbc53d78 100644 --- a/plugins/adr/package.json +++ b/plugins/adr/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-adr", - "version": "0.6.11-next.1", + "version": "0.6.11-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/airbrake-backend/CHANGELOG.md b/plugins/airbrake-backend/CHANGELOG.md index da4b51d934..d17b7163c0 100644 --- a/plugins/airbrake-backend/CHANGELOG.md +++ b/plugins/airbrake-backend/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-airbrake-backend +## 0.3.5-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + ## 0.3.5-next.1 ### Patch Changes diff --git a/plugins/airbrake-backend/package.json b/plugins/airbrake-backend/package.json index 75a2ed104e..ae21abc68d 100644 --- a/plugins/airbrake-backend/package.json +++ b/plugins/airbrake-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-airbrake-backend", - "version": "0.3.5-next.1", + "version": "0.3.5-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/airbrake/CHANGELOG.md b/plugins/airbrake/CHANGELOG.md index 19a506f8e6..73fed7ebf8 100644 --- a/plugins/airbrake/CHANGELOG.md +++ b/plugins/airbrake/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-airbrake +## 0.3.28-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/dev-utils@1.0.25-next.2 + - @backstage/test-utils@1.4.6-next.2 + ## 0.3.28-next.1 ### Patch Changes diff --git a/plugins/airbrake/package.json b/plugins/airbrake/package.json index 07a41bb804..617e0cb230 100644 --- a/plugins/airbrake/package.json +++ b/plugins/airbrake/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-airbrake", - "version": "0.3.28-next.1", + "version": "0.3.28-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/allure/CHANGELOG.md b/plugins/allure/CHANGELOG.md index ca8cdcc87b..973eb19b10 100644 --- a/plugins/allure/CHANGELOG.md +++ b/plugins/allure/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-allure +## 0.1.44-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + ## 0.1.44-next.1 ### Patch Changes diff --git a/plugins/allure/package.json b/plugins/allure/package.json index 5778ad0834..7e3cb96dcf 100644 --- a/plugins/allure/package.json +++ b/plugins/allure/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-allure", "description": "A Backstage plugin that integrates with Allure", - "version": "0.1.44-next.1", + "version": "0.1.44-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/analytics-module-ga/CHANGELOG.md b/plugins/analytics-module-ga/CHANGELOG.md index ba46e16809..4f16059c68 100644 --- a/plugins/analytics-module-ga/CHANGELOG.md +++ b/plugins/analytics-module-ga/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-analytics-module-ga +## 0.1.36-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + ## 0.1.36-next.1 ### Patch Changes diff --git a/plugins/analytics-module-ga/package.json b/plugins/analytics-module-ga/package.json index d2744caf9d..f3f736e2b8 100644 --- a/plugins/analytics-module-ga/package.json +++ b/plugins/analytics-module-ga/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-analytics-module-ga", - "version": "0.1.36-next.1", + "version": "0.1.36-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/analytics-module-ga4/CHANGELOG.md b/plugins/analytics-module-ga4/CHANGELOG.md index 2e2b17ec8d..1a92081a96 100644 --- a/plugins/analytics-module-ga4/CHANGELOG.md +++ b/plugins/analytics-module-ga4/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-analytics-module-ga4 +## 0.1.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + ## 0.1.7-next.1 ### Patch Changes diff --git a/plugins/analytics-module-ga4/package.json b/plugins/analytics-module-ga4/package.json index 246a1bf2d6..13e9e65415 100644 --- a/plugins/analytics-module-ga4/package.json +++ b/plugins/analytics-module-ga4/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-analytics-module-ga4", - "version": "0.1.7-next.1", + "version": "0.1.7-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/analytics-module-newrelic-browser/CHANGELOG.md b/plugins/analytics-module-newrelic-browser/CHANGELOG.md index f243c28481..eea3c0d58a 100644 --- a/plugins/analytics-module-newrelic-browser/CHANGELOG.md +++ b/plugins/analytics-module-newrelic-browser/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-analytics-module-newrelic-browser +## 0.0.5-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + ## 0.0.5-next.1 ### Patch Changes diff --git a/plugins/analytics-module-newrelic-browser/package.json b/plugins/analytics-module-newrelic-browser/package.json index 0cb59225cd..a146aa4adf 100644 --- a/plugins/analytics-module-newrelic-browser/package.json +++ b/plugins/analytics-module-newrelic-browser/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-analytics-module-newrelic-browser", - "version": "0.0.5-next.1", + "version": "0.0.5-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/apache-airflow/CHANGELOG.md b/plugins/apache-airflow/CHANGELOG.md index e38a08e81f..ac404ebdd5 100644 --- a/plugins/apache-airflow/CHANGELOG.md +++ b/plugins/apache-airflow/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-apache-airflow +## 0.2.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + ## 0.2.18-next.1 ### Patch Changes diff --git a/plugins/apache-airflow/package.json b/plugins/apache-airflow/package.json index 97a63fd4c1..40fbe80434 100644 --- a/plugins/apache-airflow/package.json +++ b/plugins/apache-airflow/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-apache-airflow", - "version": "0.2.18-next.1", + "version": "0.2.18-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/api-docs/CHANGELOG.md b/plugins/api-docs/CHANGELOG.md index 594448351b..646cf298fd 100644 --- a/plugins/api-docs/CHANGELOG.md +++ b/plugins/api-docs/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-api-docs +## 0.10.2-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog@1.16.0-next.3 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + ## 0.10.2-next.2 ### Patch Changes diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json index 30b8650e19..d3ff76b584 100644 --- a/plugins/api-docs/package.json +++ b/plugins/api-docs/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-api-docs", "description": "A Backstage plugin that helps represent API entities in the frontend", - "version": "0.10.2-next.2", + "version": "0.10.2-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/apollo-explorer/CHANGELOG.md b/plugins/apollo-explorer/CHANGELOG.md index ba51605e0d..41bf18cd78 100644 --- a/plugins/apollo-explorer/CHANGELOG.md +++ b/plugins/apollo-explorer/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-apollo-explorer +## 0.1.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + ## 0.1.18-next.1 ### Patch Changes diff --git a/plugins/apollo-explorer/package.json b/plugins/apollo-explorer/package.json index 0fbf80783d..84cd18b02d 100644 --- a/plugins/apollo-explorer/package.json +++ b/plugins/apollo-explorer/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-apollo-explorer", - "version": "0.1.18-next.1", + "version": "0.1.18-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/app-backend/CHANGELOG.md b/plugins/app-backend/CHANGELOG.md index 5ac1fe4aec..451ac6c219 100644 --- a/plugins/app-backend/CHANGELOG.md +++ b/plugins/app-backend/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-app-backend +## 0.3.56-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.6.0-next.0 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.8-next.2 + ## 0.3.56-next.1 ### Patch Changes diff --git a/plugins/app-backend/package.json b/plugins/app-backend/package.json index 235a7fd70b..1d888fc838 100644 --- a/plugins/app-backend/package.json +++ b/plugins/app-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-app-backend", "description": "A Backstage backend plugin that serves the Backstage frontend app", - "version": "0.3.56-next.1", + "version": "0.3.56-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/app-node/CHANGELOG.md b/plugins/app-node/CHANGELOG.md index b7069bc1c0..a0ad9dda64 100644 --- a/plugins/app-node/CHANGELOG.md +++ b/plugins/app-node/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-app-node +## 0.1.8-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.8-next.2 + ## 0.1.8-next.1 ### Patch Changes diff --git a/plugins/app-node/package.json b/plugins/app-node/package.json index b6e805c857..2121752c17 100644 --- a/plugins/app-node/package.json +++ b/plugins/app-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-app-node", "description": "Node.js library for the app plugin", - "version": "0.1.8-next.1", + "version": "0.1.8-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-backend-module-atlassian-provider/CHANGELOG.md b/plugins/auth-backend-module-atlassian-provider/CHANGELOG.md index 5eca1e2a07..79dac8b182 100644 --- a/plugins/auth-backend-module-atlassian-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-atlassian-provider/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-auth-backend-module-atlassian-provider +## 0.1.0-next.2 + +### Patch Changes + +- a62764b: Updated dependency `passport` to `^0.7.0`. +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + ## 0.1.0-next.1 ### Patch Changes diff --git a/plugins/auth-backend-module-atlassian-provider/package.json b/plugins/auth-backend-module-atlassian-provider/package.json index c2bfc37c02..f3be6d9bab 100644 --- a/plugins/auth-backend-module-atlassian-provider/package.json +++ b/plugins/auth-backend-module-atlassian-provider/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend-module-atlassian-provider", "description": "The atlassian-provider backend module for the auth plugin.", - "version": "0.1.0-next.1", + "version": "0.1.0-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-backend-module-gcp-iap-provider/CHANGELOG.md b/plugins/auth-backend-module-gcp-iap-provider/CHANGELOG.md index cfd164ebfe..c201bad5dc 100644 --- a/plugins/auth-backend-module-gcp-iap-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-gcp-iap-provider/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-auth-backend-module-gcp-iap-provider +## 0.2.2-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + ## 0.2.2-next.1 ### Patch Changes diff --git a/plugins/auth-backend-module-gcp-iap-provider/package.json b/plugins/auth-backend-module-gcp-iap-provider/package.json index f7d4ea7bc7..a1d91c3a0e 100644 --- a/plugins/auth-backend-module-gcp-iap-provider/package.json +++ b/plugins/auth-backend-module-gcp-iap-provider/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend-module-gcp-iap-provider", "description": "A GCP IAP auth provider module for the Backstage auth backend", - "version": "0.2.2-next.1", + "version": "0.2.2-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-backend-module-github-provider/CHANGELOG.md b/plugins/auth-backend-module-github-provider/CHANGELOG.md index 5b3acd377d..c13445232a 100644 --- a/plugins/auth-backend-module-github-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-github-provider/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-backend-module-github-provider +## 0.1.5-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + ## 0.1.5-next.1 ### Patch Changes diff --git a/plugins/auth-backend-module-github-provider/package.json b/plugins/auth-backend-module-github-provider/package.json index 9ed4f7d3b9..1ac20f0e63 100644 --- a/plugins/auth-backend-module-github-provider/package.json +++ b/plugins/auth-backend-module-github-provider/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend-module-github-provider", "description": "The github-provider backend module for the auth plugin.", - "version": "0.1.5-next.1", + "version": "0.1.5-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md b/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md index 03fb405e56..6223835fe9 100644 --- a/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-auth-backend-module-gitlab-provider +## 0.1.5-next.2 + +### Patch Changes + +- a62764b: Updated dependency `passport` to `^0.7.0`. +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + ## 0.1.5-next.1 ### Patch Changes diff --git a/plugins/auth-backend-module-gitlab-provider/package.json b/plugins/auth-backend-module-gitlab-provider/package.json index 56c6b43af3..79ea08e46f 100644 --- a/plugins/auth-backend-module-gitlab-provider/package.json +++ b/plugins/auth-backend-module-gitlab-provider/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend-module-gitlab-provider", "description": "The gitlab-provider backend module for the auth plugin.", - "version": "0.1.5-next.1", + "version": "0.1.5-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-backend-module-google-provider/CHANGELOG.md b/plugins/auth-backend-module-google-provider/CHANGELOG.md index 30fcf563b7..1db56eac77 100644 --- a/plugins/auth-backend-module-google-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-google-provider/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-backend-module-google-provider +## 0.1.5-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + ## 0.1.5-next.1 ### Patch Changes diff --git a/plugins/auth-backend-module-google-provider/package.json b/plugins/auth-backend-module-google-provider/package.json index 6ba15b3938..6638a28b9d 100644 --- a/plugins/auth-backend-module-google-provider/package.json +++ b/plugins/auth-backend-module-google-provider/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend-module-google-provider", "description": "A Google auth provider module for the Backstage auth backend", - "version": "0.1.5-next.1", + "version": "0.1.5-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-backend-module-microsoft-provider/CHANGELOG.md b/plugins/auth-backend-module-microsoft-provider/CHANGELOG.md index df5aea992d..06e0039d27 100644 --- a/plugins/auth-backend-module-microsoft-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-microsoft-provider/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-auth-backend-module-microsoft-provider +## 0.1.3-next.2 + +### Patch Changes + +- a62764b: Updated dependency `passport` to `^0.7.0`. +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + ## 0.1.3-next.1 ### Patch Changes diff --git a/plugins/auth-backend-module-microsoft-provider/package.json b/plugins/auth-backend-module-microsoft-provider/package.json index 47324f9ab9..c54ea24171 100644 --- a/plugins/auth-backend-module-microsoft-provider/package.json +++ b/plugins/auth-backend-module-microsoft-provider/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend-module-microsoft-provider", "description": "The microsoft-provider backend module for the auth plugin.", - "version": "0.1.3-next.1", + "version": "0.1.3-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md b/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md index 5f7a5dc4b8..30a31520ae 100644 --- a/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-auth-backend-module-oauth2-provider +## 0.1.5-next.2 + +### Patch Changes + +- a62764b: Updated dependency `passport` to `^0.7.0`. +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + ## 0.1.5-next.1 ### Patch Changes diff --git a/plugins/auth-backend-module-oauth2-provider/package.json b/plugins/auth-backend-module-oauth2-provider/package.json index f46428f4f3..e23af756f8 100644 --- a/plugins/auth-backend-module-oauth2-provider/package.json +++ b/plugins/auth-backend-module-oauth2-provider/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend-module-oauth2-provider", "description": "The oauth2-provider backend module for the auth plugin.", - "version": "0.1.5-next.1", + "version": "0.1.5-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-backend-module-oauth2-proxy-provider/CHANGELOG.md b/plugins/auth-backend-module-oauth2-proxy-provider/CHANGELOG.md index ed2ec641b9..0a4e29ffe2 100644 --- a/plugins/auth-backend-module-oauth2-proxy-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-oauth2-proxy-provider/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-auth-backend-module-oauth2-proxy-provider +## 0.1.0-next.1 + +### Patch Changes + +- a6be465: Exported the provider as default so it gets discovered when using `featureDiscoveryServiceFactory()` +- 510dab4: Change provider id from `oauth2ProxyProvider` to `oauth2Proxy` +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/errors@1.2.3 + ## 0.1.0-next.0 ### Minor Changes diff --git a/plugins/auth-backend-module-oauth2-proxy-provider/package.json b/plugins/auth-backend-module-oauth2-proxy-provider/package.json index 090a64ae66..9276176ea9 100644 --- a/plugins/auth-backend-module-oauth2-proxy-provider/package.json +++ b/plugins/auth-backend-module-oauth2-proxy-provider/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend-module-oauth2-proxy-provider", "description": "The oauth2-proxy-provider backend module for the auth plugin.", - "version": "0.1.0-next.0", + "version": "0.1.0-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-backend-module-okta-provider/CHANGELOG.md b/plugins/auth-backend-module-okta-provider/CHANGELOG.md index 6b0f8e6304..e6e91adb13 100644 --- a/plugins/auth-backend-module-okta-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-okta-provider/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-auth-backend-module-okta-provider +## 0.0.1-next.2 + +### Patch Changes + +- a62764b: Updated dependency `passport` to `^0.7.0`. +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + ## 0.0.1-next.1 ### Patch Changes diff --git a/plugins/auth-backend-module-okta-provider/package.json b/plugins/auth-backend-module-okta-provider/package.json index 178ebf1465..765ef45c6d 100644 --- a/plugins/auth-backend-module-okta-provider/package.json +++ b/plugins/auth-backend-module-okta-provider/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend-module-okta-provider", "description": "The okta-provider backend module for the auth plugin.", - "version": "0.0.1-next.1", + "version": "0.0.1-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-backend-module-pinniped-provider/CHANGELOG.md b/plugins/auth-backend-module-pinniped-provider/CHANGELOG.md index c2334029f2..d0153f1e26 100644 --- a/plugins/auth-backend-module-pinniped-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-pinniped-provider/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-auth-backend-module-pinniped-provider +## 0.1.2-next.2 + +### Patch Changes + +- a62764b: Updated dependency `passport` to `^0.7.0`. +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + ## 0.1.2-next.1 ### Patch Changes diff --git a/plugins/auth-backend-module-pinniped-provider/package.json b/plugins/auth-backend-module-pinniped-provider/package.json index 3358a9d747..0d799504a1 100644 --- a/plugins/auth-backend-module-pinniped-provider/package.json +++ b/plugins/auth-backend-module-pinniped-provider/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend-module-pinniped-provider", "description": "The pinniped-provider backend module for the auth plugin.", - "version": "0.1.2-next.1", + "version": "0.1.2-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-backend-module-vmware-cloud-provider/CHANGELOG.md b/plugins/auth-backend-module-vmware-cloud-provider/CHANGELOG.md index 332872c5cf..4defbe348e 100644 --- a/plugins/auth-backend-module-vmware-cloud-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-vmware-cloud-provider/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-auth-backend-module-vmware-cloud-provider +## 0.1.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + ## 0.1.0-next.0 ### Minor Changes diff --git a/plugins/auth-backend-module-vmware-cloud-provider/package.json b/plugins/auth-backend-module-vmware-cloud-provider/package.json index db9de2741d..6a054c2a70 100644 --- a/plugins/auth-backend-module-vmware-cloud-provider/package.json +++ b/plugins/auth-backend-module-vmware-cloud-provider/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend-module-vmware-cloud-provider", "description": "The vmware-cloud-provider backend module for the auth plugin.", - "version": "0.1.0-next.0", + "version": "0.1.0-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-backend/CHANGELOG.md b/plugins/auth-backend/CHANGELOG.md index 5e818e299a..2d89150d33 100644 --- a/plugins/auth-backend/CHANGELOG.md +++ b/plugins/auth-backend/CHANGELOG.md @@ -1,5 +1,30 @@ # @backstage/plugin-auth-backend +## 0.20.1-next.2 + +### Patch Changes + +- 783797a: fix static token issuer not being able to initialize +- a62764b: Updated dependency `passport` to `^0.7.0`. +- Updated dependencies + - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.0-next.1 + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-backend-module-atlassian-provider@0.1.0-next.2 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.1.5-next.2 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.1.5-next.2 + - @backstage/plugin-auth-backend-module-okta-provider@0.0.1-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.2-next.2 + - @backstage/plugin-auth-backend-module-google-provider@0.1.5-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-backend-module-github-provider@0.1.5-next.2 + ## 0.20.1-next.1 ### Patch Changes diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json index 2ce075087f..af5bd43f44 100644 --- a/plugins/auth-backend/package.json +++ b/plugins/auth-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend", "description": "A Backstage backend plugin that handles authentication", - "version": "0.20.1-next.1", + "version": "0.20.1-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-node/CHANGELOG.md b/plugins/auth-node/CHANGELOG.md index 8262a10dab..13c9873318 100644 --- a/plugins/auth-node/CHANGELOG.md +++ b/plugins/auth-node/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-auth-node +## 0.4.2-next.2 + +### Patch Changes + +- a62764b: Updated dependency `passport` to `^0.7.0`. +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + ## 0.4.2-next.1 ### Patch Changes diff --git a/plugins/auth-node/package.json b/plugins/auth-node/package.json index ceb1a587ce..ebdbe6d368 100644 --- a/plugins/auth-node/package.json +++ b/plugins/auth-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-node", - "version": "0.4.2-next.1", + "version": "0.4.2-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/azure-devops-backend/CHANGELOG.md b/plugins/azure-devops-backend/CHANGELOG.md index 0b4f978662..dfdeebb9b5 100644 --- a/plugins/azure-devops-backend/CHANGELOG.md +++ b/plugins/azure-devops-backend/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-azure-devops-backend +## 0.5.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/integration@1.8.0-next.1 + - @backstage/plugin-azure-devops-common@0.3.2-next.0 + - @backstage/plugin-catalog-common@1.0.18 + ## 0.5.0-next.1 ### Minor Changes diff --git a/plugins/azure-devops-backend/package.json b/plugins/azure-devops-backend/package.json index 6b223a26b2..e7fe43bdc1 100644 --- a/plugins/azure-devops-backend/package.json +++ b/plugins/azure-devops-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-azure-devops-backend", - "version": "0.5.0-next.1", + "version": "0.5.0-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/azure-devops/CHANGELOG.md b/plugins/azure-devops/CHANGELOG.md index 3cd6209099..664b581b0a 100644 --- a/plugins/azure-devops/CHANGELOG.md +++ b/plugins/azure-devops/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-azure-devops +## 0.3.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-azure-devops-common@0.3.2-next.0 + ## 0.3.10-next.1 ### Patch Changes diff --git a/plugins/azure-devops/package.json b/plugins/azure-devops/package.json index 39b14b8be2..d57031cd13 100644 --- a/plugins/azure-devops/package.json +++ b/plugins/azure-devops/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-azure-devops", - "version": "0.3.10-next.1", + "version": "0.3.10-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/azure-sites-backend/CHANGELOG.md b/plugins/azure-sites-backend/CHANGELOG.md index 19953f496a..92a1b3fb7b 100644 --- a/plugins/azure-sites-backend/CHANGELOG.md +++ b/plugins/azure-sites-backend/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-azure-sites-backend +## 0.1.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/config@1.1.1 + - @backstage/plugin-azure-sites-common@0.1.1 + ## 0.1.18-next.1 ### Patch Changes diff --git a/plugins/azure-sites-backend/package.json b/plugins/azure-sites-backend/package.json index 1a62fead17..e8537b1444 100644 --- a/plugins/azure-sites-backend/package.json +++ b/plugins/azure-sites-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-azure-sites-backend", - "version": "0.1.18-next.1", + "version": "0.1.18-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/azure-sites/CHANGELOG.md b/plugins/azure-sites/CHANGELOG.md index 95d7c4491e..05fd572694 100644 --- a/plugins/azure-sites/CHANGELOG.md +++ b/plugins/azure-sites/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-azure-sites +## 0.1.17-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/plugin-azure-sites-common@0.1.1 + ## 0.1.17-next.1 ### Patch Changes diff --git a/plugins/azure-sites/package.json b/plugins/azure-sites/package.json index e8a21a2a55..0dc57d2c5c 100644 --- a/plugins/azure-sites/package.json +++ b/plugins/azure-sites/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-azure-sites", - "version": "0.1.17-next.1", + "version": "0.1.17-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/badges-backend/CHANGELOG.md b/plugins/badges-backend/CHANGELOG.md index f424b1b04e..f384f40148 100644 --- a/plugins/badges-backend/CHANGELOG.md +++ b/plugins/badges-backend/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-badges-backend +## 0.3.5-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + ## 0.3.5-next.1 ### Patch Changes diff --git a/plugins/badges-backend/package.json b/plugins/badges-backend/package.json index 6aaae4d8ea..74f615a36e 100644 --- a/plugins/badges-backend/package.json +++ b/plugins/badges-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-badges-backend", "description": "A Backstage backend plugin that generates README badges for your entities", - "version": "0.3.5-next.1", + "version": "0.3.5-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/badges/CHANGELOG.md b/plugins/badges/CHANGELOG.md index f7330a5a9b..4db9d9b3df 100644 --- a/plugins/badges/CHANGELOG.md +++ b/plugins/badges/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-badges +## 0.2.52-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + ## 0.2.52-next.1 ### Patch Changes diff --git a/plugins/badges/package.json b/plugins/badges/package.json index 627af40a6b..297bedda13 100644 --- a/plugins/badges/package.json +++ b/plugins/badges/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-badges", "description": "A Backstage plugin that generates README badges for your entities", - "version": "0.2.52-next.1", + "version": "0.2.52-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/bazaar-backend/CHANGELOG.md b/plugins/bazaar-backend/CHANGELOG.md index 0fc8f9323d..c77f40773d 100644 --- a/plugins/bazaar-backend/CHANGELOG.md +++ b/plugins/bazaar-backend/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-bazaar-backend +## 0.3.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + ## 0.3.6-next.1 ### Patch Changes diff --git a/plugins/bazaar-backend/package.json b/plugins/bazaar-backend/package.json index 5823ebe418..a98723d2fc 100644 --- a/plugins/bazaar-backend/package.json +++ b/plugins/bazaar-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-bazaar-backend", - "version": "0.3.6-next.1", + "version": "0.3.6-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/bazaar/CHANGELOG.md b/plugins/bazaar/CHANGELOG.md index d89b8fa06b..890970ab42 100644 --- a/plugins/bazaar/CHANGELOG.md +++ b/plugins/bazaar/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-bazaar +## 0.2.20-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + ## 0.2.20-next.2 ### Patch Changes diff --git a/plugins/bazaar/package.json b/plugins/bazaar/package.json index fcf5245a4a..f0d50a38a0 100644 --- a/plugins/bazaar/package.json +++ b/plugins/bazaar/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-bazaar", - "version": "0.2.20-next.2", + "version": "0.2.20-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/bitrise/CHANGELOG.md b/plugins/bitrise/CHANGELOG.md index 46f9c95da7..0dc0ea417d 100644 --- a/plugins/bitrise/CHANGELOG.md +++ b/plugins/bitrise/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-bitrise +## 0.1.55-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + ## 0.1.55-next.1 ### Patch Changes diff --git a/plugins/bitrise/package.json b/plugins/bitrise/package.json index 47d35cbe58..f5a2ad5158 100644 --- a/plugins/bitrise/package.json +++ b/plugins/bitrise/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-bitrise", "description": "A Backstage plugin that integrates towards Bitrise", - "version": "0.1.55-next.1", + "version": "0.1.55-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-aws/CHANGELOG.md b/plugins/catalog-backend-module-aws/CHANGELOG.md index 94d8f6913c..b2be9f907b 100644 --- a/plugins/catalog-backend-module-aws/CHANGELOG.md +++ b/plugins/catalog-backend-module-aws/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-catalog-backend-module-aws +## 0.3.2-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/integration-aws-node@0.1.8 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.18 + - @backstage/plugin-kubernetes-common@0.7.2-next.1 + ## 0.3.2-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-aws/package.json b/plugins/catalog-backend-module-aws/package.json index 7dc89cd13e..88da2472a4 100644 --- a/plugins/catalog-backend-module-aws/package.json +++ b/plugins/catalog-backend-module-aws/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-aws", "description": "A Backstage catalog backend module that helps integrate towards AWS", - "version": "0.3.2-next.1", + "version": "0.3.2-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-azure/CHANGELOG.md b/plugins/catalog-backend-module-azure/CHANGELOG.md index e34657c198..c2df3d355d 100644 --- a/plugins/catalog-backend-module-azure/CHANGELOG.md +++ b/plugins/catalog-backend-module-azure/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-catalog-backend-module-azure +## 0.1.27-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.18 + ## 0.1.27-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-azure/package.json b/plugins/catalog-backend-module-azure/package.json index 8425b22331..31778ef43d 100644 --- a/plugins/catalog-backend-module-azure/package.json +++ b/plugins/catalog-backend-module-azure/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-azure", "description": "A Backstage catalog backend module that helps integrate towards Azure", - "version": "0.1.27-next.1", + "version": "0.1.27-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-backstage-openapi/CHANGELOG.md b/plugins/catalog-backend-module-backstage-openapi/CHANGELOG.md index db59c77fc4..274b0a243d 100644 --- a/plugins/catalog-backend-module-backstage-openapi/CHANGELOG.md +++ b/plugins/catalog-backend-module-backstage-openapi/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-backend-module-backstage-openapi +## 0.1.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-openapi-utils@0.1.1-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + ## 0.1.1-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-backstage-openapi/package.json b/plugins/catalog-backend-module-backstage-openapi/package.json index dc3fc37508..6d2b058182 100644 --- a/plugins/catalog-backend-module-backstage-openapi/package.json +++ b/plugins/catalog-backend-module-backstage-openapi/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-backstage-openapi", - "version": "0.1.1-next.1", + "version": "0.1.1-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md index 4f54bad476..933646cc0b 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-catalog-backend-module-bitbucket-cloud +## 0.1.23-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/integration@1.8.0-next.1 + - @backstage/plugin-bitbucket-cloud-common@0.2.15-next.1 + - @backstage/plugin-catalog-common@1.0.18 + - @backstage/plugin-events-node@0.2.17-next.2 + ## 0.1.23-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-bitbucket-cloud/package.json b/plugins/catalog-backend-module-bitbucket-cloud/package.json index 6848617058..15c9af2e10 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/package.json +++ b/plugins/catalog-backend-module-bitbucket-cloud/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-bitbucket-cloud", "description": "A Backstage catalog backend module that helps integrate towards Bitbucket Cloud", - "version": "0.1.23-next.1", + "version": "0.1.23-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md index 71e47ddb6c..b91d501796 100644 --- a/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-catalog-backend-module-bitbucket-server +## 0.1.21-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + ## 0.1.21-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-bitbucket-server/package.json b/plugins/catalog-backend-module-bitbucket-server/package.json index bf2130422b..743c99dba3 100644 --- a/plugins/catalog-backend-module-bitbucket-server/package.json +++ b/plugins/catalog-backend-module-bitbucket-server/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-bitbucket-server", - "version": "0.1.21-next.1", + "version": "0.1.21-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-bitbucket/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket/CHANGELOG.md index 3ceec86c77..0f03b82750 100644 --- a/plugins/catalog-backend-module-bitbucket/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-backend-module-bitbucket +## 0.2.23-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-bitbucket-cloud-common@0.2.15-next.1 + ## 0.2.23-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-bitbucket/package.json b/plugins/catalog-backend-module-bitbucket/package.json index 75eb671f30..44b17b1059 100644 --- a/plugins/catalog-backend-module-bitbucket/package.json +++ b/plugins/catalog-backend-module-bitbucket/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-bitbucket", "description": "A Backstage catalog backend module that helps integrate towards Bitbucket", - "version": "0.2.23-next.1", + "version": "0.2.23-next.2", "deprecated": true, "main": "src/index.ts", "types": "src/index.ts", diff --git a/plugins/catalog-backend-module-gcp/CHANGELOG.md b/plugins/catalog-backend-module-gcp/CHANGELOG.md index 3af2589342..2154ebcc71 100644 --- a/plugins/catalog-backend-module-gcp/CHANGELOG.md +++ b/plugins/catalog-backend-module-gcp/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-backend-module-gcp +## 0.1.8-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/plugin-kubernetes-common@0.7.2-next.1 + ## 0.1.8-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-gcp/package.json b/plugins/catalog-backend-module-gcp/package.json index e68aeaec66..d788957128 100644 --- a/plugins/catalog-backend-module-gcp/package.json +++ b/plugins/catalog-backend-module-gcp/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-gcp", "description": "A Backstage catalog backend module that helps integrate towards GCP", - "version": "0.1.8-next.1", + "version": "0.1.8-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-gerrit/CHANGELOG.md b/plugins/catalog-backend-module-gerrit/CHANGELOG.md index 6251a978b4..3bd9863e48 100644 --- a/plugins/catalog-backend-module-gerrit/CHANGELOG.md +++ b/plugins/catalog-backend-module-gerrit/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-catalog-backend-module-gerrit +## 0.1.24-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + ## 0.1.24-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-gerrit/package.json b/plugins/catalog-backend-module-gerrit/package.json index 2bccaa62c2..57d53211de 100644 --- a/plugins/catalog-backend-module-gerrit/package.json +++ b/plugins/catalog-backend-module-gerrit/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-gerrit", - "version": "0.1.24-next.1", + "version": "0.1.24-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-github-org/CHANGELOG.md b/plugins/catalog-backend-module-github-org/CHANGELOG.md index dd857af17c..5cb7ba5a44 100644 --- a/plugins/catalog-backend-module-github-org/CHANGELOG.md +++ b/plugins/catalog-backend-module-github-org/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend-module-github-org +## 0.1.2-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-catalog-backend-module-github@0.4.6-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/config@1.1.1 + ## 0.1.2-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-github-org/package.json b/plugins/catalog-backend-module-github-org/package.json index b2d2904bc8..6c16a3bc68 100644 --- a/plugins/catalog-backend-module-github-org/package.json +++ b/plugins/catalog-backend-module-github-org/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-github-org", "description": "The github-org backend module for the catalog plugin.", - "version": "0.1.2-next.1", + "version": "0.1.2-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-github/CHANGELOG.md b/plugins/catalog-backend-module-github/CHANGELOG.md index 780e095568..ceaefdcf45 100644 --- a/plugins/catalog-backend-module-github/CHANGELOG.md +++ b/plugins/catalog-backend-module-github/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-catalog-backend-module-github +## 0.4.6-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/plugin-catalog-backend@1.16.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/integration@1.8.0-next.1 + - @backstage/plugin-catalog-common@1.0.18 + - @backstage/plugin-events-node@0.2.17-next.2 + ## 0.4.6-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-github/package.json b/plugins/catalog-backend-module-github/package.json index 08f86b7feb..c0618db04a 100644 --- a/plugins/catalog-backend-module-github/package.json +++ b/plugins/catalog-backend-module-github/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-github", "description": "A Backstage catalog backend module that helps integrate towards GitHub", - "version": "0.4.6-next.1", + "version": "0.4.6-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-gitlab/CHANGELOG.md b/plugins/catalog-backend-module-gitlab/CHANGELOG.md index 816002bd55..0c9320a93b 100644 --- a/plugins/catalog-backend-module-gitlab/CHANGELOG.md +++ b/plugins/catalog-backend-module-gitlab/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-backend-module-gitlab +## 0.3.5-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/integration@1.8.0-next.1 + ## 0.3.5-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-gitlab/package.json b/plugins/catalog-backend-module-gitlab/package.json index 0a9728756c..6a21d7305c 100644 --- a/plugins/catalog-backend-module-gitlab/package.json +++ b/plugins/catalog-backend-module-gitlab/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-gitlab", "description": "A Backstage catalog backend module that helps integrate towards GitLab", - "version": "0.3.5-next.1", + "version": "0.3.5-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md b/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md index d62732c7c2..19c5f4f4d2 100644 --- a/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md +++ b/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-catalog-backend-module-incremental-ingestion +## 0.4.12-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/plugin-catalog-backend@1.16.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-events-node@0.2.17-next.2 + - @backstage/plugin-permission-common@0.7.10 + ## 0.4.12-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-incremental-ingestion/package.json b/plugins/catalog-backend-module-incremental-ingestion/package.json index 003ee93d6a..2bb3a44ddd 100644 --- a/plugins/catalog-backend-module-incremental-ingestion/package.json +++ b/plugins/catalog-backend-module-incremental-ingestion/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-incremental-ingestion", "description": "An entity provider for streaming large asset sources into the catalog", - "version": "0.4.12-next.1", + "version": "0.4.12-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-ldap/CHANGELOG.md b/plugins/catalog-backend-module-ldap/CHANGELOG.md index 29a73c7239..966ff2c58e 100644 --- a/plugins/catalog-backend-module-ldap/CHANGELOG.md +++ b/plugins/catalog-backend-module-ldap/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend-module-ldap +## 0.5.23-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.18 + ## 0.5.23-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-ldap/package.json b/plugins/catalog-backend-module-ldap/package.json index 1fcf31f572..cf57d50b54 100644 --- a/plugins/catalog-backend-module-ldap/package.json +++ b/plugins/catalog-backend-module-ldap/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-ldap", "description": "A Backstage catalog backend module that helps integrate towards LDAP", - "version": "0.5.23-next.1", + "version": "0.5.23-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-msgraph/CHANGELOG.md b/plugins/catalog-backend-module-msgraph/CHANGELOG.md index ecdff69a6b..82b11514ab 100644 --- a/plugins/catalog-backend-module-msgraph/CHANGELOG.md +++ b/plugins/catalog-backend-module-msgraph/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend-module-msgraph +## 0.5.15-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/plugin-catalog-common@1.0.18 + ## 0.5.15-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-msgraph/package.json b/plugins/catalog-backend-module-msgraph/package.json index e5767dbf10..643dd45c40 100644 --- a/plugins/catalog-backend-module-msgraph/package.json +++ b/plugins/catalog-backend-module-msgraph/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-msgraph", "description": "A Backstage catalog backend module that helps integrate towards Microsoft Graph", - "version": "0.5.15-next.1", + "version": "0.5.15-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-openapi/CHANGELOG.md b/plugins/catalog-backend-module-openapi/CHANGELOG.md index 297b1d9393..2458e33db7 100644 --- a/plugins/catalog-backend-module-openapi/CHANGELOG.md +++ b/plugins/catalog-backend-module-openapi/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-backend-module-openapi +## 0.1.25-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/plugin-catalog-backend@1.16.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/integration@1.8.0-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.18 + ## 0.1.25-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-openapi/package.json b/plugins/catalog-backend-module-openapi/package.json index d1c3d7b605..4345352936 100644 --- a/plugins/catalog-backend-module-openapi/package.json +++ b/plugins/catalog-backend-module-openapi/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-openapi", "description": "A Backstage catalog backend module that helps with OpenAPI specifications", - "version": "0.1.25-next.1", + "version": "0.1.25-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-puppetdb/CHANGELOG.md b/plugins/catalog-backend-module-puppetdb/CHANGELOG.md index 0679c1f6e5..ef386630cf 100644 --- a/plugins/catalog-backend-module-puppetdb/CHANGELOG.md +++ b/plugins/catalog-backend-module-puppetdb/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-catalog-backend-module-puppetdb +## 0.1.13-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + ## 0.1.13-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-puppetdb/package.json b/plugins/catalog-backend-module-puppetdb/package.json index e908a1806a..22e971fba8 100644 --- a/plugins/catalog-backend-module-puppetdb/package.json +++ b/plugins/catalog-backend-module-puppetdb/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-puppetdb", "description": "A Backstage catalog backend module that helps integrate towards PuppetDB", - "version": "0.1.13-next.1", + "version": "0.1.13-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md b/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md index 56edf10313..327b06a061 100644 --- a/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md +++ b/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend-module-scaffolder-entity-model +## 0.1.5-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/plugin-catalog-common@1.0.18 + - @backstage/plugin-scaffolder-common@1.4.3 + ## 0.1.5-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-scaffolder-entity-model/package.json b/plugins/catalog-backend-module-scaffolder-entity-model/package.json index ed1bf21a26..99522b8ed4 100644 --- a/plugins/catalog-backend-module-scaffolder-entity-model/package.json +++ b/plugins/catalog-backend-module-scaffolder-entity-model/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-scaffolder-entity-model", "description": "Adds support for the scaffolder specific entity model (e.g. the Template kind) to the catalog backend plugin.", - "version": "0.1.5-next.1", + "version": "0.1.5-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-unprocessed/CHANGELOG.md b/plugins/catalog-backend-module-unprocessed/CHANGELOG.md index 3bf8cf6245..4fb935f6c5 100644 --- a/plugins/catalog-backend-module-unprocessed/CHANGELOG.md +++ b/plugins/catalog-backend-module-unprocessed/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-catalog-backend-module-unprocessed +## 0.3.5-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + ## 0.3.5-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-unprocessed/package.json b/plugins/catalog-backend-module-unprocessed/package.json index 3e4efb5715..6cdb7ccdb3 100644 --- a/plugins/catalog-backend-module-unprocessed/package.json +++ b/plugins/catalog-backend-module-unprocessed/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-unprocessed", "description": "Backstage Catalog module to view unprocessed entities", - "version": "0.3.5-next.1", + "version": "0.3.5-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend/CHANGELOG.md b/plugins/catalog-backend/CHANGELOG.md index c689547470..ba71758d45 100644 --- a/plugins/catalog-backend/CHANGELOG.md +++ b/plugins/catalog-backend/CHANGELOG.md @@ -1,5 +1,34 @@ # @backstage/plugin-catalog-backend +## 1.16.0-next.2 + +### Minor Changes + +- 7804597: Permission rules can now be added for the Catalog plugin through the `CatalogPermissionExtensionPoint` interface. + +### Patch Changes + +- 50ee804: Wrap single `pipelineLoop` of TaskPipeline in a span for better traces +- a168507: Deprecated `EntitiesSearchFilter` and `EntityFilter`, which can now be imported from `@backstage/plugin-catalog-node` instead +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/plugin-search-backend-module-catalog@0.1.12-next.2 + - @backstage/backend-openapi-utils@0.1.1-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.18 + - @backstage/plugin-events-node@0.2.17-next.2 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-permission-node@0.7.19-next.2 + ## 1.15.1-next.1 ### Patch Changes diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index cd83510bdc..8525cc4834 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend", "description": "The Backstage backend plugin that provides the Backstage catalog", - "version": "1.15.1-next.1", + "version": "1.16.0-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-graph/CHANGELOG.md b/plugins/catalog-graph/CHANGELOG.md index a91217563d..9e22aeb07e 100644 --- a/plugins/catalog-graph/CHANGELOG.md +++ b/plugins/catalog-graph/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-graph +## 0.3.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/types@1.1.1 + ## 0.3.2-next.1 ### Patch Changes diff --git a/plugins/catalog-graph/package.json b/plugins/catalog-graph/package.json index 2552f38f8a..940a9d2092 100644 --- a/plugins/catalog-graph/package.json +++ b/plugins/catalog-graph/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-graph", - "version": "0.3.2-next.1", + "version": "0.3.2-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-import/CHANGELOG.md b/plugins/catalog-import/CHANGELOG.md index 347d787911..df10c3e57b 100644 --- a/plugins/catalog-import/CHANGELOG.md +++ b/plugins/catalog-import/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/plugin-catalog-import +## 0.10.4-next.3 + +### Patch Changes + +- a1227cc: Wrap `/alpha` export extension elements in backwards compatibility wrapper. +- 36c94b8: Refactor of the alpha exports due to API change in how extension IDs are constructed. +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/core-compat-api@0.1.0-next.2 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/integration-react@1.1.22-next.1 + - @backstage/plugin-catalog-common@1.0.18 + ## 0.10.4-next.2 ### Patch Changes diff --git a/plugins/catalog-import/package.json b/plugins/catalog-import/package.json index be0793b026..f40345bafb 100644 --- a/plugins/catalog-import/package.json +++ b/plugins/catalog-import/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-import", "description": "A Backstage plugin the helps you import entities into your catalog", - "version": "0.10.4-next.2", + "version": "0.10.4-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-node/CHANGELOG.md b/plugins/catalog-node/CHANGELOG.md index 175d4c33c0..82692baf4a 100644 --- a/plugins/catalog-node/CHANGELOG.md +++ b/plugins/catalog-node/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-catalog-node +## 1.6.0-next.2 + +### Minor Changes + +- a168507: Added `EntitiesSearchFilter` and `EntityFilter` from `@backstage/plugin-catalog-backend`, for reuse +- 7804597: Permission rules can now be added for the Catalog plugin through the `CatalogPermissionExtensionPoint` interface. + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.18 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-permission-node@0.7.19-next.2 + ## 1.5.1-next.1 ### Patch Changes diff --git a/plugins/catalog-node/package.json b/plugins/catalog-node/package.json index 85ca35831c..d76092b076 100644 --- a/plugins/catalog-node/package.json +++ b/plugins/catalog-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-node", "description": "The plugin-catalog-node module for @backstage/plugin-catalog-backend", - "version": "1.5.1-next.1", + "version": "1.6.0-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-react/CHANGELOG.md b/plugins/catalog-react/CHANGELOG.md index c4618fc659..3f87a2647e 100644 --- a/plugins/catalog-react/CHANGELOG.md +++ b/plugins/catalog-react/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-catalog-react +## 1.9.2-next.2 + +### Patch Changes + +- 8f5d6c1: Updates to the `/alpha` exports to match the extension input wrapping change. +- 36c94b8: Refactor of the alpha exports due to API change in how extension IDs are constructed. +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/theme@0.5.0-next.1 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/integration-react@1.1.22-next.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-catalog-common@1.0.18 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-permission-react@0.4.18-next.1 + ## 1.9.2-next.1 ### Patch Changes diff --git a/plugins/catalog-react/package.json b/plugins/catalog-react/package.json index 4869b44cb8..4761b9abbc 100644 --- a/plugins/catalog-react/package.json +++ b/plugins/catalog-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-react", "description": "A frontend library that helps other Backstage plugins interact with the catalog", - "version": "1.9.2-next.1", + "version": "1.9.2-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-unprocessed-entities/CHANGELOG.md b/plugins/catalog-unprocessed-entities/CHANGELOG.md index 171f26282a..be54f6fd00 100644 --- a/plugins/catalog-unprocessed-entities/CHANGELOG.md +++ b/plugins/catalog-unprocessed-entities/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-catalog-unprocessed-entities +## 0.1.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + ## 0.1.6-next.1 ### Patch Changes diff --git a/plugins/catalog-unprocessed-entities/package.json b/plugins/catalog-unprocessed-entities/package.json index a443949861..12a805c2fd 100644 --- a/plugins/catalog-unprocessed-entities/package.json +++ b/plugins/catalog-unprocessed-entities/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-unprocessed-entities", - "version": "0.1.6-next.1", + "version": "0.1.6-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog/CHANGELOG.md b/plugins/catalog/CHANGELOG.md index 02a765dcf4..319ec22fa6 100644 --- a/plugins/catalog/CHANGELOG.md +++ b/plugins/catalog/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-catalog +## 1.16.0-next.3 + +### Patch Changes + +- a1227cc: Wrap `/alpha` export extension elements in backwards compatibility wrapper. +- 8f5d6c1: Updates to the `/alpha` exports to match the extension input wrapping change. +- 36c94b8: Refactor of the alpha exports due to API change in how extension IDs are constructed. +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/theme@0.5.0-next.1 + - @backstage/core-compat-api@0.1.0-next.2 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/plugin-search-react@1.7.4-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/integration-react@1.1.22-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.18 + - @backstage/plugin-scaffolder-common@1.4.3 + - @backstage/plugin-search-common@1.2.8 + ## 1.16.0-next.2 ### Minor Changes diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json index 88ee613922..12d66efedb 100644 --- a/plugins/catalog/package.json +++ b/plugins/catalog/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog", "description": "The Backstage plugin for browsing the Backstage catalog", - "version": "1.16.0-next.2", + "version": "1.16.0-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/cicd-statistics-module-gitlab/CHANGELOG.md b/plugins/cicd-statistics-module-gitlab/CHANGELOG.md index 0a86a58cc5..b9dba4590c 100644 --- a/plugins/cicd-statistics-module-gitlab/CHANGELOG.md +++ b/plugins/cicd-statistics-module-gitlab/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-cicd-statistics-module-gitlab +## 0.1.24-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.3 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/plugin-cicd-statistics@0.1.30-next.2 + ## 0.1.24-next.1 ### Patch Changes diff --git a/plugins/cicd-statistics-module-gitlab/package.json b/plugins/cicd-statistics-module-gitlab/package.json index 534060d805..aa3bfa17c0 100644 --- a/plugins/cicd-statistics-module-gitlab/package.json +++ b/plugins/cicd-statistics-module-gitlab/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-cicd-statistics-module-gitlab", "description": "CI/CD Statistics plugin module; Gitlab CICD", - "version": "0.1.24-next.1", + "version": "0.1.24-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/cicd-statistics/CHANGELOG.md b/plugins/cicd-statistics/CHANGELOG.md index 187f00e25f..419a70f0e1 100644 --- a/plugins/cicd-statistics/CHANGELOG.md +++ b/plugins/cicd-statistics/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-cicd-statistics +## 0.1.30-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-plugin-api@1.8.1-next.1 + ## 0.1.30-next.1 ### Patch Changes diff --git a/plugins/cicd-statistics/package.json b/plugins/cicd-statistics/package.json index f2bf5b9a64..f660fb3466 100644 --- a/plugins/cicd-statistics/package.json +++ b/plugins/cicd-statistics/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-cicd-statistics", "description": "A frontend plugin visualizing CI/CD pipeline statistics (build time)", - "version": "0.1.30-next.1", + "version": "0.1.30-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/circleci/CHANGELOG.md b/plugins/circleci/CHANGELOG.md index 4740e2afb6..ca28077dd0 100644 --- a/plugins/circleci/CHANGELOG.md +++ b/plugins/circleci/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-circleci +## 0.3.28-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + ## 0.3.28-next.1 ### Patch Changes diff --git a/plugins/circleci/package.json b/plugins/circleci/package.json index b3dadfb55b..977962ac75 100644 --- a/plugins/circleci/package.json +++ b/plugins/circleci/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-circleci", "description": "A Backstage plugin that integrates towards Circle CI", - "version": "0.3.28-next.1", + "version": "0.3.28-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/cloudbuild/CHANGELOG.md b/plugins/cloudbuild/CHANGELOG.md index b4403f7678..bc43903bb6 100644 --- a/plugins/cloudbuild/CHANGELOG.md +++ b/plugins/cloudbuild/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-cloudbuild +## 0.3.28-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + ## 0.3.28-next.1 ### Patch Changes diff --git a/plugins/cloudbuild/package.json b/plugins/cloudbuild/package.json index f480404563..f25cccd169 100644 --- a/plugins/cloudbuild/package.json +++ b/plugins/cloudbuild/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-cloudbuild", "description": "A Backstage plugin that integrates towards Google Cloud Build", - "version": "0.3.28-next.1", + "version": "0.3.28-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/code-climate/CHANGELOG.md b/plugins/code-climate/CHANGELOG.md index b10c55fe3a..a90f606447 100644 --- a/plugins/code-climate/CHANGELOG.md +++ b/plugins/code-climate/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-code-climate +## 0.1.28-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + ## 0.1.28-next.1 ### Patch Changes diff --git a/plugins/code-climate/package.json b/plugins/code-climate/package.json index f0800fce83..8c04865875 100644 --- a/plugins/code-climate/package.json +++ b/plugins/code-climate/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-code-climate", - "version": "0.1.28-next.1", + "version": "0.1.28-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/code-coverage-backend/CHANGELOG.md b/plugins/code-coverage-backend/CHANGELOG.md index 37aedd5dce..deaf2c0f4f 100644 --- a/plugins/code-coverage-backend/CHANGELOG.md +++ b/plugins/code-coverage-backend/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-code-coverage-backend +## 0.2.22-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + ## 0.2.22-next.1 ### Patch Changes diff --git a/plugins/code-coverage-backend/package.json b/plugins/code-coverage-backend/package.json index 61f21d7438..e0b1c15ccf 100644 --- a/plugins/code-coverage-backend/package.json +++ b/plugins/code-coverage-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-code-coverage-backend", "description": "A Backstage backend plugin that helps you keep track of your code coverage", - "version": "0.2.22-next.1", + "version": "0.2.22-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/code-coverage/CHANGELOG.md b/plugins/code-coverage/CHANGELOG.md index d64996306c..a0ab67a5eb 100644 --- a/plugins/code-coverage/CHANGELOG.md +++ b/plugins/code-coverage/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-code-coverage +## 0.2.21-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + ## 0.2.21-next.1 ### Patch Changes diff --git a/plugins/code-coverage/package.json b/plugins/code-coverage/package.json index e03d65a7b2..227c7b5fc8 100644 --- a/plugins/code-coverage/package.json +++ b/plugins/code-coverage/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-code-coverage", "description": "A Backstage plugin that helps you keep track of your code coverage", - "version": "0.2.21-next.1", + "version": "0.2.21-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/codescene/CHANGELOG.md b/plugins/codescene/CHANGELOG.md index 2d7f295123..c11691896a 100644 --- a/plugins/codescene/CHANGELOG.md +++ b/plugins/codescene/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-codescene +## 0.1.20-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + ## 0.1.20-next.1 ### Patch Changes diff --git a/plugins/codescene/package.json b/plugins/codescene/package.json index d21f66ac2b..d464f7ee85 100644 --- a/plugins/codescene/package.json +++ b/plugins/codescene/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-codescene", - "version": "0.1.20-next.1", + "version": "0.1.20-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/config-schema/CHANGELOG.md b/plugins/config-schema/CHANGELOG.md index b57892c764..0409799b68 100644 --- a/plugins/config-schema/CHANGELOG.md +++ b/plugins/config-schema/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-config-schema +## 0.1.48-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + ## 0.1.48-next.1 ### Patch Changes diff --git a/plugins/config-schema/package.json b/plugins/config-schema/package.json index 12740e5f49..ce63fa086b 100644 --- a/plugins/config-schema/package.json +++ b/plugins/config-schema/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-config-schema", "description": "A Backstage plugin that lets you browse the configuration schema of your app", - "version": "0.1.48-next.1", + "version": "0.1.48-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/cost-insights/CHANGELOG.md b/plugins/cost-insights/CHANGELOG.md index c941b62f66..231b3d426a 100644 --- a/plugins/cost-insights/CHANGELOG.md +++ b/plugins/cost-insights/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-cost-insights +## 0.12.17-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/plugin-cost-insights-common@0.1.2 + ## 0.12.17-next.1 ### Patch Changes diff --git a/plugins/cost-insights/package.json b/plugins/cost-insights/package.json index c9258bc464..2582bb04b7 100644 --- a/plugins/cost-insights/package.json +++ b/plugins/cost-insights/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-cost-insights", "description": "A Backstage plugin that helps you keep track of your cloud spend", - "version": "0.12.17-next.1", + "version": "0.12.17-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/devtools-backend/CHANGELOG.md b/plugins/devtools-backend/CHANGELOG.md index 655743c818..b333d869f3 100644 --- a/plugins/devtools-backend/CHANGELOG.md +++ b/plugins/devtools-backend/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-devtools-backend +## 0.2.5-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.6.0-next.0 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-devtools-common@0.1.6 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-permission-node@0.7.19-next.2 + ## 0.2.5-next.1 ### Patch Changes diff --git a/plugins/devtools-backend/package.json b/plugins/devtools-backend/package.json index b445c25ae6..358d710b0d 100644 --- a/plugins/devtools-backend/package.json +++ b/plugins/devtools-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-devtools-backend", - "version": "0.2.5-next.1", + "version": "0.2.5-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/devtools/CHANGELOG.md b/plugins/devtools/CHANGELOG.md index a71d43fbd8..c964fe5efe 100644 --- a/plugins/devtools/CHANGELOG.md +++ b/plugins/devtools/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-devtools +## 0.1.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-devtools-common@0.1.6 + - @backstage/plugin-permission-react@0.4.18-next.1 + ## 0.1.7-next.1 ### Patch Changes diff --git a/plugins/devtools/package.json b/plugins/devtools/package.json index 67cbae9802..34b12ebc3d 100644 --- a/plugins/devtools/package.json +++ b/plugins/devtools/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-devtools", - "version": "0.1.7-next.1", + "version": "0.1.7-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/dynatrace/CHANGELOG.md b/plugins/dynatrace/CHANGELOG.md index 102f88c562..1d6999a63d 100644 --- a/plugins/dynatrace/CHANGELOG.md +++ b/plugins/dynatrace/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-dynatrace +## 8.0.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + ## 8.0.2-next.1 ### Patch Changes diff --git a/plugins/dynatrace/package.json b/plugins/dynatrace/package.json index 552ebfaed3..654b0d5df6 100644 --- a/plugins/dynatrace/package.json +++ b/plugins/dynatrace/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-dynatrace", - "version": "8.0.2-next.1", + "version": "8.0.2-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/entity-feedback-backend/CHANGELOG.md b/plugins/entity-feedback-backend/CHANGELOG.md index 101e8b0654..23e4cd1c5f 100644 --- a/plugins/entity-feedback-backend/CHANGELOG.md +++ b/plugins/entity-feedback-backend/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-entity-feedback-backend +## 0.2.5-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/plugin-entity-feedback-common@0.1.3 + ## 0.2.5-next.1 ### Patch Changes diff --git a/plugins/entity-feedback-backend/package.json b/plugins/entity-feedback-backend/package.json index c232a67307..b91c57f6dc 100644 --- a/plugins/entity-feedback-backend/package.json +++ b/plugins/entity-feedback-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-entity-feedback-backend", - "version": "0.2.5-next.1", + "version": "0.2.5-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/entity-feedback/CHANGELOG.md b/plugins/entity-feedback/CHANGELOG.md index 622d5c98f8..721087414c 100644 --- a/plugins/entity-feedback/CHANGELOG.md +++ b/plugins/entity-feedback/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-entity-feedback +## 0.2.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-entity-feedback-common@0.1.3 + ## 0.2.11-next.1 ### Patch Changes diff --git a/plugins/entity-feedback/package.json b/plugins/entity-feedback/package.json index ab6c40e51e..9e90fbdd97 100644 --- a/plugins/entity-feedback/package.json +++ b/plugins/entity-feedback/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-entity-feedback", - "version": "0.2.11-next.1", + "version": "0.2.11-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/entity-validation/CHANGELOG.md b/plugins/entity-validation/CHANGELOG.md index 843be5d6d1..383aa44ed8 100644 --- a/plugins/entity-validation/CHANGELOG.md +++ b/plugins/entity-validation/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-entity-validation +## 0.1.13-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-catalog-common@1.0.18 + ## 0.1.13-next.1 ### Patch Changes diff --git a/plugins/entity-validation/package.json b/plugins/entity-validation/package.json index dc0bd93565..65534acc76 100644 --- a/plugins/entity-validation/package.json +++ b/plugins/entity-validation/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-entity-validation", - "version": "0.1.13-next.1", + "version": "0.1.13-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-backend-module-aws-sqs/CHANGELOG.md b/plugins/events-backend-module-aws-sqs/CHANGELOG.md index 113a641795..879335c401 100644 --- a/plugins/events-backend-module-aws-sqs/CHANGELOG.md +++ b/plugins/events-backend-module-aws-sqs/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-events-backend-module-aws-sqs +## 0.2.11-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.2.17-next.2 + ## 0.2.11-next.1 ### Patch Changes diff --git a/plugins/events-backend-module-aws-sqs/package.json b/plugins/events-backend-module-aws-sqs/package.json index 627aedd0be..8bdd7b93bc 100644 --- a/plugins/events-backend-module-aws-sqs/package.json +++ b/plugins/events-backend-module-aws-sqs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-aws-sqs", - "version": "0.2.11-next.1", + "version": "0.2.11-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-backend-module-azure/CHANGELOG.md b/plugins/events-backend-module-azure/CHANGELOG.md index e5ae8e0536..4ebc628da0 100644 --- a/plugins/events-backend-module-azure/CHANGELOG.md +++ b/plugins/events-backend-module-azure/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-events-backend-module-azure +## 0.1.18-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/plugin-events-node@0.2.17-next.2 + ## 0.1.18-next.1 ### Patch Changes diff --git a/plugins/events-backend-module-azure/package.json b/plugins/events-backend-module-azure/package.json index 7908478ba7..1ed2869432 100644 --- a/plugins/events-backend-module-azure/package.json +++ b/plugins/events-backend-module-azure/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-azure", - "version": "0.1.18-next.1", + "version": "0.1.18-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md b/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md index d33369f7b5..cc2ee606ea 100644 --- a/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md +++ b/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-events-backend-module-bitbucket-cloud +## 0.1.18-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/plugin-events-node@0.2.17-next.2 + ## 0.1.18-next.1 ### Patch Changes diff --git a/plugins/events-backend-module-bitbucket-cloud/package.json b/plugins/events-backend-module-bitbucket-cloud/package.json index ed1c10f433..3c8a6aa028 100644 --- a/plugins/events-backend-module-bitbucket-cloud/package.json +++ b/plugins/events-backend-module-bitbucket-cloud/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-bitbucket-cloud", - "version": "0.1.18-next.1", + "version": "0.1.18-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-backend-module-gerrit/CHANGELOG.md b/plugins/events-backend-module-gerrit/CHANGELOG.md index 156a8f24d8..28edd10328 100644 --- a/plugins/events-backend-module-gerrit/CHANGELOG.md +++ b/plugins/events-backend-module-gerrit/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-events-backend-module-gerrit +## 0.1.18-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/plugin-events-node@0.2.17-next.2 + ## 0.1.18-next.1 ### Patch Changes diff --git a/plugins/events-backend-module-gerrit/package.json b/plugins/events-backend-module-gerrit/package.json index 24a70d19bf..a561a52eaa 100644 --- a/plugins/events-backend-module-gerrit/package.json +++ b/plugins/events-backend-module-gerrit/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-gerrit", - "version": "0.1.18-next.1", + "version": "0.1.18-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-backend-module-github/CHANGELOG.md b/plugins/events-backend-module-github/CHANGELOG.md index 725de56c46..d06becd7db 100644 --- a/plugins/events-backend-module-github/CHANGELOG.md +++ b/plugins/events-backend-module-github/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-events-backend-module-github +## 0.1.18-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + - @backstage/plugin-events-node@0.2.17-next.2 + ## 0.1.18-next.1 ### Patch Changes diff --git a/plugins/events-backend-module-github/package.json b/plugins/events-backend-module-github/package.json index fe57a4ffbd..8639513699 100644 --- a/plugins/events-backend-module-github/package.json +++ b/plugins/events-backend-module-github/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-github", - "version": "0.1.18-next.1", + "version": "0.1.18-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-backend-module-gitlab/CHANGELOG.md b/plugins/events-backend-module-gitlab/CHANGELOG.md index c13f8865d5..8bb110a240 100644 --- a/plugins/events-backend-module-gitlab/CHANGELOG.md +++ b/plugins/events-backend-module-gitlab/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-events-backend-module-gitlab +## 0.1.18-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + - @backstage/plugin-events-node@0.2.17-next.2 + ## 0.1.18-next.1 ### Patch Changes diff --git a/plugins/events-backend-module-gitlab/package.json b/plugins/events-backend-module-gitlab/package.json index b8000bbe2e..92453d78c2 100644 --- a/plugins/events-backend-module-gitlab/package.json +++ b/plugins/events-backend-module-gitlab/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-gitlab", - "version": "0.1.18-next.1", + "version": "0.1.18-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-backend-test-utils/CHANGELOG.md b/plugins/events-backend-test-utils/CHANGELOG.md index 96b8d616ea..5861eaa428 100644 --- a/plugins/events-backend-test-utils/CHANGELOG.md +++ b/plugins/events-backend-test-utils/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-events-backend-test-utils +## 0.1.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.2.17-next.2 + ## 0.1.18-next.1 ### Patch Changes diff --git a/plugins/events-backend-test-utils/package.json b/plugins/events-backend-test-utils/package.json index ddb5ab31d1..837b188adc 100644 --- a/plugins/events-backend-test-utils/package.json +++ b/plugins/events-backend-test-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-events-backend-test-utils", "description": "The plugin-events-backend-test-utils for @backstage/plugin-events-node", - "version": "0.1.18-next.1", + "version": "0.1.18-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-backend/CHANGELOG.md b/plugins/events-backend/CHANGELOG.md index 80cfe97cc2..9ac727208f 100644 --- a/plugins/events-backend/CHANGELOG.md +++ b/plugins/events-backend/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-events-backend +## 0.2.17-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + - @backstage/plugin-events-node@0.2.17-next.2 + ## 0.2.17-next.1 ### Patch Changes diff --git a/plugins/events-backend/package.json b/plugins/events-backend/package.json index f6c3398952..ace840a60c 100644 --- a/plugins/events-backend/package.json +++ b/plugins/events-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend", - "version": "0.2.17-next.1", + "version": "0.2.17-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-node/CHANGELOG.md b/plugins/events-node/CHANGELOG.md index 4c2b466971..edacba99cd 100644 --- a/plugins/events-node/CHANGELOG.md +++ b/plugins/events-node/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-events-node +## 0.2.17-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.8-next.2 + ## 0.2.17-next.1 ### Patch Changes diff --git a/plugins/events-node/package.json b/plugins/events-node/package.json index b56c54125f..fea1a0ff82 100644 --- a/plugins/events-node/package.json +++ b/plugins/events-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-events-node", "description": "The plugin-events-node module for @backstage/plugin-events-backend", - "version": "0.2.17-next.1", + "version": "0.2.17-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/example-todo-list-backend/CHANGELOG.md b/plugins/example-todo-list-backend/CHANGELOG.md index 36106c9b4b..698f0bd2d4 100644 --- a/plugins/example-todo-list-backend/CHANGELOG.md +++ b/plugins/example-todo-list-backend/CHANGELOG.md @@ -1,5 +1,16 @@ # @internal/plugin-todo-list-backend +## 1.0.20-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + ## 1.0.20-next.1 ### Patch Changes diff --git a/plugins/example-todo-list-backend/package.json b/plugins/example-todo-list-backend/package.json index ad2997423a..81ac1adcac 100644 --- a/plugins/example-todo-list-backend/package.json +++ b/plugins/example-todo-list-backend/package.json @@ -1,6 +1,6 @@ { "name": "@internal/plugin-todo-list-backend", - "version": "1.0.20-next.1", + "version": "1.0.20-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/example-todo-list/CHANGELOG.md b/plugins/example-todo-list/CHANGELOG.md index 0e7e213137..e49acee4c1 100644 --- a/plugins/example-todo-list/CHANGELOG.md +++ b/plugins/example-todo-list/CHANGELOG.md @@ -1,5 +1,14 @@ # @internal/plugin-todo-list +## 1.0.20-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + ## 1.0.20-next.1 ### Patch Changes diff --git a/plugins/example-todo-list/package.json b/plugins/example-todo-list/package.json index 9538280e94..484b02601d 100644 --- a/plugins/example-todo-list/package.json +++ b/plugins/example-todo-list/package.json @@ -1,6 +1,6 @@ { "name": "@internal/plugin-todo-list", - "version": "1.0.20-next.1", + "version": "1.0.20-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/explore-backend/CHANGELOG.md b/plugins/explore-backend/CHANGELOG.md index c880ce5374..9f3d3c837e 100644 --- a/plugins/explore-backend/CHANGELOG.md +++ b/plugins/explore-backend/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-explore-backend +## 0.0.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-search-backend-module-explore@0.1.12-next.2 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-search-common@1.2.8 + ## 0.0.18-next.1 ### Patch Changes diff --git a/plugins/explore-backend/package.json b/plugins/explore-backend/package.json index 8f53a106d6..f444599527 100644 --- a/plugins/explore-backend/package.json +++ b/plugins/explore-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-explore-backend", - "version": "0.0.18-next.1", + "version": "0.0.18-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/explore/CHANGELOG.md b/plugins/explore/CHANGELOG.md index 8a42d288fe..9d8535deba 100644 --- a/plugins/explore/CHANGELOG.md +++ b/plugins/explore/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-explore +## 0.4.14-next.2 + +### Patch Changes + +- 36c94b8: Refactor of the alpha exports due to API change in how extension IDs are constructed. +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/plugin-search-react@1.7.4-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-explore-react@0.0.34-next.1 + - @backstage/plugin-search-common@1.2.8 + ## 0.4.14-next.1 ### Patch Changes diff --git a/plugins/explore/package.json b/plugins/explore/package.json index 382b3b6691..341640dbbf 100644 --- a/plugins/explore/package.json +++ b/plugins/explore/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-explore", "description": "A Backstage plugin for building an exploration page of your software ecosystem", - "version": "0.4.14-next.1", + "version": "0.4.14-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/firehydrant/CHANGELOG.md b/plugins/firehydrant/CHANGELOG.md index fff099f63c..23612fd132 100644 --- a/plugins/firehydrant/CHANGELOG.md +++ b/plugins/firehydrant/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-firehydrant +## 0.2.12-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + ## 0.2.12-next.1 ### Patch Changes diff --git a/plugins/firehydrant/package.json b/plugins/firehydrant/package.json index 953bebce22..b16e34dd3a 100644 --- a/plugins/firehydrant/package.json +++ b/plugins/firehydrant/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-firehydrant", "description": "A Backstage plugin that integrates towards FireHydrant", - "version": "0.2.12-next.1", + "version": "0.2.12-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/fossa/CHANGELOG.md b/plugins/fossa/CHANGELOG.md index 26e1272aa8..79e357e510 100644 --- a/plugins/fossa/CHANGELOG.md +++ b/plugins/fossa/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-fossa +## 0.2.60-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + ## 0.2.60-next.1 ### Patch Changes diff --git a/plugins/fossa/package.json b/plugins/fossa/package.json index cca6446a46..9cc11ba6d1 100644 --- a/plugins/fossa/package.json +++ b/plugins/fossa/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-fossa", "description": "A Backstage plugin that integrates towards FOSSA", - "version": "0.2.60-next.1", + "version": "0.2.60-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/gcalendar/CHANGELOG.md b/plugins/gcalendar/CHANGELOG.md index 627f65b156..d27cbd1c53 100644 --- a/plugins/gcalendar/CHANGELOG.md +++ b/plugins/gcalendar/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-gcalendar +## 0.3.21-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + ## 0.3.21-next.1 ### Patch Changes diff --git a/plugins/gcalendar/package.json b/plugins/gcalendar/package.json index 8bd2d578e2..eb3df7606a 100644 --- a/plugins/gcalendar/package.json +++ b/plugins/gcalendar/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-gcalendar", - "version": "0.3.21-next.1", + "version": "0.3.21-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/gcp-projects/CHANGELOG.md b/plugins/gcp-projects/CHANGELOG.md index 65d1fe430e..32785c6523 100644 --- a/plugins/gcp-projects/CHANGELOG.md +++ b/plugins/gcp-projects/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-gcp-projects +## 0.3.44-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + ## 0.3.44-next.1 ### Patch Changes diff --git a/plugins/gcp-projects/package.json b/plugins/gcp-projects/package.json index 004309ebb6..c025fb5781 100644 --- a/plugins/gcp-projects/package.json +++ b/plugins/gcp-projects/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-gcp-projects", "description": "A Backstage plugin that helps you manage projects in GCP", - "version": "0.3.44-next.1", + "version": "0.3.44-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/git-release-manager/CHANGELOG.md b/plugins/git-release-manager/CHANGELOG.md index e4737858c3..72a56328c2 100644 --- a/plugins/git-release-manager/CHANGELOG.md +++ b/plugins/git-release-manager/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-git-release-manager +## 0.3.40-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/integration@1.8.0-next.1 + ## 0.3.40-next.1 ### Patch Changes diff --git a/plugins/git-release-manager/package.json b/plugins/git-release-manager/package.json index b0380670e4..12df99ac0e 100644 --- a/plugins/git-release-manager/package.json +++ b/plugins/git-release-manager/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-git-release-manager", "description": "A Backstage plugin that helps you manage releases in git", - "version": "0.3.40-next.1", + "version": "0.3.40-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/github-actions/CHANGELOG.md b/plugins/github-actions/CHANGELOG.md index 78f9b7a699..757e4f6c41 100644 --- a/plugins/github-actions/CHANGELOG.md +++ b/plugins/github-actions/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-github-actions +## 0.6.9-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/integration@1.8.0-next.1 + - @backstage/integration-react@1.1.22-next.1 + ## 0.6.9-next.1 ### Patch Changes diff --git a/plugins/github-actions/package.json b/plugins/github-actions/package.json index 3d47fa4ed8..e8e9a4712a 100644 --- a/plugins/github-actions/package.json +++ b/plugins/github-actions/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-github-actions", "description": "A Backstage plugin that integrates towards GitHub Actions", - "version": "0.6.9-next.1", + "version": "0.6.9-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/github-deployments/CHANGELOG.md b/plugins/github-deployments/CHANGELOG.md index cab881189f..7cf3d34d42 100644 --- a/plugins/github-deployments/CHANGELOG.md +++ b/plugins/github-deployments/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-github-deployments +## 0.1.59-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/integration-react@1.1.22-next.1 + ## 0.1.59-next.1 ### Patch Changes diff --git a/plugins/github-deployments/package.json b/plugins/github-deployments/package.json index 8db532b20e..0aed35feda 100644 --- a/plugins/github-deployments/package.json +++ b/plugins/github-deployments/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-github-deployments", "description": "A Backstage plugin that integrates towards GitHub Deployments", - "version": "0.1.59-next.1", + "version": "0.1.59-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/github-issues/CHANGELOG.md b/plugins/github-issues/CHANGELOG.md index 473c325dd4..93a26f0267 100644 --- a/plugins/github-issues/CHANGELOG.md +++ b/plugins/github-issues/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-github-issues +## 0.2.17-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + ## 0.2.17-next.1 ### Patch Changes diff --git a/plugins/github-issues/package.json b/plugins/github-issues/package.json index d8b19cf5df..80c117457d 100644 --- a/plugins/github-issues/package.json +++ b/plugins/github-issues/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-github-issues", - "version": "0.2.17-next.1", + "version": "0.2.17-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/github-pull-requests-board/CHANGELOG.md b/plugins/github-pull-requests-board/CHANGELOG.md index 2e697a4771..582bda0c5c 100644 --- a/plugins/github-pull-requests-board/CHANGELOG.md +++ b/plugins/github-pull-requests-board/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-github-pull-requests-board +## 0.1.22-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/integration@1.8.0-next.1 + ## 0.1.22-next.1 ### Patch Changes diff --git a/plugins/github-pull-requests-board/package.json b/plugins/github-pull-requests-board/package.json index b160ae27e8..4f1808838d 100644 --- a/plugins/github-pull-requests-board/package.json +++ b/plugins/github-pull-requests-board/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-github-pull-requests-board", "description": "A Backstage plugin that allows you to see all open Pull Requests for all the repositories owned by your team", - "version": "0.1.22-next.1", + "version": "0.1.22-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/gitops-profiles/CHANGELOG.md b/plugins/gitops-profiles/CHANGELOG.md index 24aa989eff..8aed7b63cb 100644 --- a/plugins/gitops-profiles/CHANGELOG.md +++ b/plugins/gitops-profiles/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-gitops-profiles +## 0.3.43-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + ## 0.3.43-next.1 ### Patch Changes diff --git a/plugins/gitops-profiles/package.json b/plugins/gitops-profiles/package.json index d599d328be..e1fbea8112 100644 --- a/plugins/gitops-profiles/package.json +++ b/plugins/gitops-profiles/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-gitops-profiles", "description": "A Backstage plugin that helps you manage GitOps profiles", - "version": "0.3.43-next.1", + "version": "0.3.43-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/gocd/CHANGELOG.md b/plugins/gocd/CHANGELOG.md index 54be67883c..468e843212 100644 --- a/plugins/gocd/CHANGELOG.md +++ b/plugins/gocd/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-gocd +## 0.1.34-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + ## 0.1.34-next.1 ### Patch Changes diff --git a/plugins/gocd/package.json b/plugins/gocd/package.json index 54358233fd..3d597f1ef3 100644 --- a/plugins/gocd/package.json +++ b/plugins/gocd/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-gocd", "description": "A Backstage plugin that integrates towards GoCD", - "version": "0.1.34-next.1", + "version": "0.1.34-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/graphiql/CHANGELOG.md b/plugins/graphiql/CHANGELOG.md index 4d339dea27..6b97494401 100644 --- a/plugins/graphiql/CHANGELOG.md +++ b/plugins/graphiql/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-graphiql +## 0.3.1-next.3 + +### Patch Changes + +- a1227cc: Wrap `/alpha` export extension elements in backwards compatibility wrapper. +- 8f5d6c1: Updates to the `/alpha` exports to match the extension input wrapping change. +- 36c94b8: Refactor of the alpha exports due to API change in how extension IDs are constructed. +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/theme@0.5.0-next.1 + - @backstage/core-compat-api@0.1.0-next.2 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + ## 0.3.1-next.2 ### Patch Changes diff --git a/plugins/graphiql/package.json b/plugins/graphiql/package.json index 7ed0f98285..0746180f76 100644 --- a/plugins/graphiql/package.json +++ b/plugins/graphiql/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-graphiql", "description": "Backstage plugin for browsing GraphQL APIs", - "version": "0.3.1-next.2", + "version": "0.3.1-next.3", "publishConfig": { "access": "public" }, diff --git a/plugins/graphql-voyager/CHANGELOG.md b/plugins/graphql-voyager/CHANGELOG.md index 033e22a800..9979c83b57 100644 --- a/plugins/graphql-voyager/CHANGELOG.md +++ b/plugins/graphql-voyager/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-graphql-voyager +## 0.1.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + ## 0.1.10-next.1 ### Patch Changes diff --git a/plugins/graphql-voyager/package.json b/plugins/graphql-voyager/package.json index 88ba1bd92b..02239ad24e 100644 --- a/plugins/graphql-voyager/package.json +++ b/plugins/graphql-voyager/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-graphql-voyager", "description": "Backstage plugin for GraphQL Voyager", - "version": "0.1.10-next.1", + "version": "0.1.10-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/home-react/CHANGELOG.md b/plugins/home-react/CHANGELOG.md index 989c43dafe..ca7a0a66f7 100644 --- a/plugins/home-react/CHANGELOG.md +++ b/plugins/home-react/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-home-react +## 0.1.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + ## 0.1.6-next.1 ### Patch Changes diff --git a/plugins/home-react/package.json b/plugins/home-react/package.json index 60dc92c3e7..f2b1b94e48 100644 --- a/plugins/home-react/package.json +++ b/plugins/home-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-home-react", "description": "A Backstage plugin that contains react components helps you build a home page", - "version": "0.1.6-next.1", + "version": "0.1.6-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/home/CHANGELOG.md b/plugins/home/CHANGELOG.md index dc8f69358f..c842969c35 100644 --- a/plugins/home/CHANGELOG.md +++ b/plugins/home/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-home +## 0.6.0-next.2 + +### Patch Changes + +- a1227cc: Wrap `/alpha` export extension elements in backwards compatibility wrapper. +- 8f5d6c1: Updates to the `/alpha` exports to match the extension input wrapping change. +- 36c94b8: Refactor of the alpha exports due to API change in how extension IDs are constructed. +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/theme@0.5.0-next.1 + - @backstage/core-compat-api@0.1.0-next.2 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-app-api@1.11.2-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-home-react@0.1.6-next.2 + ## 0.6.0-next.1 ### Minor Changes diff --git a/plugins/home/package.json b/plugins/home/package.json index 038037e303..489105866c 100644 --- a/plugins/home/package.json +++ b/plugins/home/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-home", "description": "A Backstage plugin that helps you build a home page", - "version": "0.6.0-next.1", + "version": "0.6.0-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/ilert/CHANGELOG.md b/plugins/ilert/CHANGELOG.md index 30203b9bb7..7204e88a35 100644 --- a/plugins/ilert/CHANGELOG.md +++ b/plugins/ilert/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-ilert +## 0.2.17-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + ## 0.2.17-next.1 ### Patch Changes diff --git a/plugins/ilert/package.json b/plugins/ilert/package.json index 567f60f281..baab866298 100644 --- a/plugins/ilert/package.json +++ b/plugins/ilert/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-ilert", "description": "A Backstage plugin that integrates towards iLert", - "version": "0.2.17-next.1", + "version": "0.2.17-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/jenkins-backend/CHANGELOG.md b/plugins/jenkins-backend/CHANGELOG.md index 63337d737c..b71ee98880 100644 --- a/plugins/jenkins-backend/CHANGELOG.md +++ b/plugins/jenkins-backend/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-jenkins-backend +## 0.3.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-jenkins-common@0.1.21 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-permission-node@0.7.19-next.2 + ## 0.3.2-next.1 ### Patch Changes diff --git a/plugins/jenkins-backend/package.json b/plugins/jenkins-backend/package.json index 2e8b9ab3dc..0da77035c5 100644 --- a/plugins/jenkins-backend/package.json +++ b/plugins/jenkins-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-jenkins-backend", "description": "A Backstage backend plugin that integrates towards Jenkins", - "version": "0.3.2-next.1", + "version": "0.3.2-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/jenkins/CHANGELOG.md b/plugins/jenkins/CHANGELOG.md index d8c722d101..79d1ba0252 100644 --- a/plugins/jenkins/CHANGELOG.md +++ b/plugins/jenkins/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-jenkins +## 0.9.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-jenkins-common@0.1.21 + ## 0.9.3-next.1 ### Patch Changes diff --git a/plugins/jenkins/package.json b/plugins/jenkins/package.json index c372414a03..f48e582d56 100644 --- a/plugins/jenkins/package.json +++ b/plugins/jenkins/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-jenkins", "description": "A Backstage plugin that integrates towards Jenkins", - "version": "0.9.3-next.1", + "version": "0.9.3-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/kafka-backend/CHANGELOG.md b/plugins/kafka-backend/CHANGELOG.md index f56a155e2c..7e2b20ef10 100644 --- a/plugins/kafka-backend/CHANGELOG.md +++ b/plugins/kafka-backend/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-kafka-backend +## 0.3.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + ## 0.3.6-next.1 ### Patch Changes diff --git a/plugins/kafka-backend/package.json b/plugins/kafka-backend/package.json index b61139f4ce..2af508e167 100644 --- a/plugins/kafka-backend/package.json +++ b/plugins/kafka-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kafka-backend", "description": "A Backstage backend plugin that integrates towards Kafka", - "version": "0.3.6-next.1", + "version": "0.3.6-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/kafka/CHANGELOG.md b/plugins/kafka/CHANGELOG.md index c81f09daef..ec2931df26 100644 --- a/plugins/kafka/CHANGELOG.md +++ b/plugins/kafka/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-kafka +## 0.3.28-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + ## 0.3.28-next.1 ### Patch Changes diff --git a/plugins/kafka/package.json b/plugins/kafka/package.json index b4f827f11a..5b4941d12a 100644 --- a/plugins/kafka/package.json +++ b/plugins/kafka/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kafka", "description": "A Backstage plugin that integrates towards Kafka", - "version": "0.3.28-next.1", + "version": "0.3.28-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/kubernetes-backend/CHANGELOG.md b/plugins/kubernetes-backend/CHANGELOG.md index 6938eed660..70260944eb 100644 --- a/plugins/kubernetes-backend/CHANGELOG.md +++ b/plugins/kubernetes-backend/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/plugin-kubernetes-backend +## 0.14.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration-aws-node@0.1.8 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.7.2-next.1 + - @backstage/plugin-kubernetes-node@0.1.2-next.2 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-permission-node@0.7.19-next.2 + ## 0.14.0-next.1 ### Patch Changes diff --git a/plugins/kubernetes-backend/package.json b/plugins/kubernetes-backend/package.json index d485a1163a..bb20057e92 100644 --- a/plugins/kubernetes-backend/package.json +++ b/plugins/kubernetes-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kubernetes-backend", "description": "A Backstage backend plugin that integrates towards Kubernetes", - "version": "0.14.0-next.1", + "version": "0.14.0-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/kubernetes-cluster/CHANGELOG.md b/plugins/kubernetes-cluster/CHANGELOG.md index 4ae5fcf0ae..12f22f4927 100644 --- a/plugins/kubernetes-cluster/CHANGELOG.md +++ b/plugins/kubernetes-cluster/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-kubernetes-cluster +## 0.0.4-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-kubernetes-react@0.2.0-next.2 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-kubernetes-common@0.7.2-next.1 + ## 0.0.4-next.1 ### Patch Changes diff --git a/plugins/kubernetes-cluster/package.json b/plugins/kubernetes-cluster/package.json index f113325644..c3fb1e2bf8 100644 --- a/plugins/kubernetes-cluster/package.json +++ b/plugins/kubernetes-cluster/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kubernetes-cluster", "description": "A Backstage plugin that shows details of Kubernetes clusters", - "version": "0.0.4-next.1", + "version": "0.0.4-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/kubernetes-node/CHANGELOG.md b/plugins/kubernetes-node/CHANGELOG.md index d87d7a3cc8..449b0288bf 100644 --- a/plugins/kubernetes-node/CHANGELOG.md +++ b/plugins/kubernetes-node/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-kubernetes-node +## 0.1.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/plugin-kubernetes-common@0.7.2-next.1 + ## 0.1.2-next.1 ### Patch Changes diff --git a/plugins/kubernetes-node/package.json b/plugins/kubernetes-node/package.json index 852ce00d83..43f8b341f1 100644 --- a/plugins/kubernetes-node/package.json +++ b/plugins/kubernetes-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kubernetes-node", "description": "Node.js library for the kubernetes plugin", - "version": "0.1.2-next.1", + "version": "0.1.2-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/kubernetes-react/CHANGELOG.md b/plugins/kubernetes-react/CHANGELOG.md index 03ef769a99..fd7dc3a1cb 100644 --- a/plugins/kubernetes-react/CHANGELOG.md +++ b/plugins/kubernetes-react/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-kubernetes-react +## 0.2.0-next.2 + +### Minor Changes + +- 899d71a: Change `formatClusterLink` to be an API and make it async for further customization possibilities. + + **BREAKING** + If you have a custom k8s page and used `formatClusterLink` directly, you need to migrate to new `kubernetesClusterLinkFormatterApiRef` + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.7.2-next.1 + ## 0.1.2-next.1 ### Patch Changes diff --git a/plugins/kubernetes-react/package.json b/plugins/kubernetes-react/package.json index bacf82acd6..27be86c436 100644 --- a/plugins/kubernetes-react/package.json +++ b/plugins/kubernetes-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kubernetes-react", "description": "Web library for the kubernetes-react plugin", - "version": "0.1.2-next.1", + "version": "0.2.0-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/kubernetes/CHANGELOG.md b/plugins/kubernetes/CHANGELOG.md index 0131eca6ce..f637aa6f21 100644 --- a/plugins/kubernetes/CHANGELOG.md +++ b/plugins/kubernetes/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-kubernetes +## 0.11.3-next.2 + +### Patch Changes + +- 899d71a: Change `formatClusterLink` to be an API and make it async for further customization possibilities. + + **BREAKING** + If you have a custom k8s page and used `formatClusterLink` directly, you need to migrate to new `kubernetesClusterLinkFormatterApiRef` + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-kubernetes-react@0.2.0-next.2 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.7.2-next.1 + ## 0.11.3-next.1 ### Patch Changes diff --git a/plugins/kubernetes/package.json b/plugins/kubernetes/package.json index 897e1abe04..d1cd6d9f2b 100644 --- a/plugins/kubernetes/package.json +++ b/plugins/kubernetes/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kubernetes", "description": "A Backstage plugin that integrates towards Kubernetes", - "version": "0.11.3-next.1", + "version": "0.11.3-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/lighthouse-backend/CHANGELOG.md b/plugins/lighthouse-backend/CHANGELOG.md index f5a92f575b..4eb0649118 100644 --- a/plugins/lighthouse-backend/CHANGELOG.md +++ b/plugins/lighthouse-backend/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-lighthouse-backend +## 0.4.0-next.2 + +### Minor Changes + +- 7f0dbfd: Fixed crashes faced with custom schedule configuration. The configuration schema has been update to leverage the TaskScheduleDefinition interface. It is highly recommended to move the `lighthouse.shedule` and `lighthouse.timeout` respectively to `lighthouse.schedule.frequency` and `lighthouse.schedule.timeout`. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/plugin-lighthouse-common@0.1.4 + ## 0.3.5-next.1 ### Patch Changes diff --git a/plugins/lighthouse-backend/package.json b/plugins/lighthouse-backend/package.json index a143ec77d9..3e1f608fa2 100644 --- a/plugins/lighthouse-backend/package.json +++ b/plugins/lighthouse-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-lighthouse-backend", "description": "Backend functionalities for lighthouse", - "version": "0.3.5-next.1", + "version": "0.4.0-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/lighthouse/CHANGELOG.md b/plugins/lighthouse/CHANGELOG.md index 4ebf99dbd3..aaf69f195f 100644 --- a/plugins/lighthouse/CHANGELOG.md +++ b/plugins/lighthouse/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-lighthouse +## 0.4.13-next.2 + +### Patch Changes + +- ffbf656: Updated README +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/plugin-lighthouse-common@0.1.4 + ## 0.4.13-next.1 ### Patch Changes diff --git a/plugins/lighthouse/package.json b/plugins/lighthouse/package.json index 348ae348ff..ec15c89b22 100644 --- a/plugins/lighthouse/package.json +++ b/plugins/lighthouse/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-lighthouse", "description": "A Backstage plugin that integrates towards Lighthouse", - "version": "0.4.13-next.1", + "version": "0.4.13-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/linguist-backend/CHANGELOG.md b/plugins/linguist-backend/CHANGELOG.md index ff680b0db5..c983efe3ac 100644 --- a/plugins/linguist-backend/CHANGELOG.md +++ b/plugins/linguist-backend/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-linguist-backend +## 0.5.5-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-linguist-common@0.1.2 + ## 0.5.5-next.1 ### Patch Changes diff --git a/plugins/linguist-backend/package.json b/plugins/linguist-backend/package.json index 13f27b1f94..ed22dd5490 100644 --- a/plugins/linguist-backend/package.json +++ b/plugins/linguist-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-linguist-backend", - "version": "0.5.5-next.1", + "version": "0.5.5-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/linguist/CHANGELOG.md b/plugins/linguist/CHANGELOG.md index a8177709b6..f57f43ac2e 100644 --- a/plugins/linguist/CHANGELOG.md +++ b/plugins/linguist/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-linguist +## 0.1.13-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-linguist-common@0.1.2 + ## 0.1.13-next.1 ### Patch Changes diff --git a/plugins/linguist/package.json b/plugins/linguist/package.json index 630357d283..102b9bff18 100644 --- a/plugins/linguist/package.json +++ b/plugins/linguist/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-linguist", - "version": "0.1.13-next.1", + "version": "0.1.13-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/microsoft-calendar/CHANGELOG.md b/plugins/microsoft-calendar/CHANGELOG.md index 9fa9dcd330..e6bad4915b 100644 --- a/plugins/microsoft-calendar/CHANGELOG.md +++ b/plugins/microsoft-calendar/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-microsoft-calendar +## 0.1.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + ## 0.1.10-next.1 ### Patch Changes diff --git a/plugins/microsoft-calendar/package.json b/plugins/microsoft-calendar/package.json index c49892a12f..201f8597a7 100644 --- a/plugins/microsoft-calendar/package.json +++ b/plugins/microsoft-calendar/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-microsoft-calendar", - "version": "0.1.10-next.1", + "version": "0.1.10-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/newrelic-dashboard/CHANGELOG.md b/plugins/newrelic-dashboard/CHANGELOG.md index e0b1a555d8..02f911e9c2 100644 --- a/plugins/newrelic-dashboard/CHANGELOG.md +++ b/plugins/newrelic-dashboard/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-newrelic-dashboard +## 0.3.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + ## 0.3.3-next.1 ### Patch Changes diff --git a/plugins/newrelic-dashboard/package.json b/plugins/newrelic-dashboard/package.json index bbf7e0db14..fdb6bfd773 100644 --- a/plugins/newrelic-dashboard/package.json +++ b/plugins/newrelic-dashboard/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-newrelic-dashboard", - "version": "0.3.3-next.1", + "version": "0.3.3-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/newrelic/CHANGELOG.md b/plugins/newrelic/CHANGELOG.md index 2eacc6f9de..a383872f77 100644 --- a/plugins/newrelic/CHANGELOG.md +++ b/plugins/newrelic/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-newrelic +## 0.3.43-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + ## 0.3.43-next.1 ### Patch Changes diff --git a/plugins/newrelic/package.json b/plugins/newrelic/package.json index 328acc6dc6..5c9ecef1e8 100644 --- a/plugins/newrelic/package.json +++ b/plugins/newrelic/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-newrelic", "description": "A Backstage plugin that integrates towards New Relic", - "version": "0.3.43-next.1", + "version": "0.3.43-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/nomad-backend/CHANGELOG.md b/plugins/nomad-backend/CHANGELOG.md index c9ce70c9bd..b0f600672e 100644 --- a/plugins/nomad-backend/CHANGELOG.md +++ b/plugins/nomad-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-nomad-backend +## 0.1.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + ## 0.1.10-next.1 ### Patch Changes diff --git a/plugins/nomad-backend/package.json b/plugins/nomad-backend/package.json index 9b3236a36c..5f109fd142 100644 --- a/plugins/nomad-backend/package.json +++ b/plugins/nomad-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-nomad-backend", - "version": "0.1.10-next.1", + "version": "0.1.10-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/nomad/CHANGELOG.md b/plugins/nomad/CHANGELOG.md index db3028d3be..4626f99381 100644 --- a/plugins/nomad/CHANGELOG.md +++ b/plugins/nomad/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-nomad +## 0.1.9-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + ## 0.1.9-next.1 ### Patch Changes diff --git a/plugins/nomad/package.json b/plugins/nomad/package.json index 8f6c1bdaa0..a29a41ef54 100644 --- a/plugins/nomad/package.json +++ b/plugins/nomad/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-nomad", - "version": "0.1.9-next.1", + "version": "0.1.9-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/octopus-deploy/CHANGELOG.md b/plugins/octopus-deploy/CHANGELOG.md index 5be0493e2e..dcd86b5017 100644 --- a/plugins/octopus-deploy/CHANGELOG.md +++ b/plugins/octopus-deploy/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-octopus-deploy +## 0.2.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + ## 0.2.10-next.1 ### Patch Changes diff --git a/plugins/octopus-deploy/package.json b/plugins/octopus-deploy/package.json index 29c3bf0e77..4fb1531c81 100644 --- a/plugins/octopus-deploy/package.json +++ b/plugins/octopus-deploy/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-octopus-deploy", - "version": "0.2.10-next.1", + "version": "0.2.10-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/opencost/CHANGELOG.md b/plugins/opencost/CHANGELOG.md index 0bd056f1db..89c3196aa4 100644 --- a/plugins/opencost/CHANGELOG.md +++ b/plugins/opencost/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-opencost +## 0.2.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + ## 0.2.3-next.1 ### Patch Changes diff --git a/plugins/opencost/package.json b/plugins/opencost/package.json index 7c868ebeb1..661bbe7d30 100644 --- a/plugins/opencost/package.json +++ b/plugins/opencost/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-opencost", - "version": "0.2.3-next.1", + "version": "0.2.3-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/org-react/CHANGELOG.md b/plugins/org-react/CHANGELOG.md index 285d048652..46a35be48f 100644 --- a/plugins/org-react/CHANGELOG.md +++ b/plugins/org-react/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-org-react +## 0.1.17-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + ## 0.1.17-next.1 ### Patch Changes diff --git a/plugins/org-react/package.json b/plugins/org-react/package.json index af1daff510..5dcd90f16c 100644 --- a/plugins/org-react/package.json +++ b/plugins/org-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-org-react", - "version": "0.1.17-next.1", + "version": "0.1.17-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/org/CHANGELOG.md b/plugins/org/CHANGELOG.md index e5099316fa..7e52a97fbd 100644 --- a/plugins/org/CHANGELOG.md +++ b/plugins/org/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-org +## 0.6.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + ## 0.6.18-next.1 ### Patch Changes diff --git a/plugins/org/package.json b/plugins/org/package.json index 2f087eedd5..3e006fb958 100644 --- a/plugins/org/package.json +++ b/plugins/org/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-org", "description": "A Backstage plugin that helps you create entity pages for your organization", - "version": "0.6.18-next.1", + "version": "0.6.18-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/pagerduty/CHANGELOG.md b/plugins/pagerduty/CHANGELOG.md index e62d0366f1..239b7cc44d 100644 --- a/plugins/pagerduty/CHANGELOG.md +++ b/plugins/pagerduty/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-pagerduty +## 0.7.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-home-react@0.1.6-next.2 + ## 0.7.0-next.1 ### Minor Changes diff --git a/plugins/pagerduty/package.json b/plugins/pagerduty/package.json index 0e6a0667dc..b719a6e11d 100644 --- a/plugins/pagerduty/package.json +++ b/plugins/pagerduty/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-pagerduty", "description": "This plugin has been deprecated, consider using [@pagerduty/backstage-plugin](https://github.com/pagerduty/backstage-plugin) instead.", - "version": "0.7.0-next.1", + "version": "0.7.0-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/periskop-backend/CHANGELOG.md b/plugins/periskop-backend/CHANGELOG.md index 1b98851c12..1bf2436a66 100644 --- a/plugins/periskop-backend/CHANGELOG.md +++ b/plugins/periskop-backend/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-periskop-backend +## 0.2.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + ## 0.2.6-next.1 ### Patch Changes diff --git a/plugins/periskop-backend/package.json b/plugins/periskop-backend/package.json index 481533c1ed..ed392e5337 100644 --- a/plugins/periskop-backend/package.json +++ b/plugins/periskop-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-periskop-backend", - "version": "0.2.6-next.1", + "version": "0.2.6-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/periskop/CHANGELOG.md b/plugins/periskop/CHANGELOG.md index 17573f96b5..7af0c55969 100644 --- a/plugins/periskop/CHANGELOG.md +++ b/plugins/periskop/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-periskop +## 0.1.26-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + ## 0.1.26-next.1 ### Patch Changes diff --git a/plugins/periskop/package.json b/plugins/periskop/package.json index 380f7d5fd7..2e5f75da03 100644 --- a/plugins/periskop/package.json +++ b/plugins/periskop/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-periskop", - "version": "0.1.26-next.1", + "version": "0.1.26-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/permission-backend-module-policy-allow-all/CHANGELOG.md b/plugins/permission-backend-module-policy-allow-all/CHANGELOG.md index 8b46dfe282..7a893efe16 100644 --- a/plugins/permission-backend-module-policy-allow-all/CHANGELOG.md +++ b/plugins/permission-backend-module-policy-allow-all/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-permission-backend-module-allow-all-policy +## 0.1.5-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-permission-node@0.7.19-next.2 + ## 0.1.5-next.1 ### Patch Changes diff --git a/plugins/permission-backend-module-policy-allow-all/package.json b/plugins/permission-backend-module-policy-allow-all/package.json index b65ff60cfb..3d3d5889f2 100644 --- a/plugins/permission-backend-module-policy-allow-all/package.json +++ b/plugins/permission-backend-module-policy-allow-all/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-permission-backend-module-allow-all-policy", "description": "Allow all policy backend module for the permission plugin.", - "version": "0.1.5-next.1", + "version": "0.1.5-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/permission-backend/CHANGELOG.md b/plugins/permission-backend/CHANGELOG.md index 85c74ef3cb..8ccc1e1b9d 100644 --- a/plugins/permission-backend/CHANGELOG.md +++ b/plugins/permission-backend/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-permission-backend +## 0.5.31-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-permission-node@0.7.19-next.2 + ## 0.5.31-next.1 ### Patch Changes diff --git a/plugins/permission-backend/package.json b/plugins/permission-backend/package.json index 3578b55a81..2b95f48511 100644 --- a/plugins/permission-backend/package.json +++ b/plugins/permission-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-permission-backend", - "version": "0.5.31-next.1", + "version": "0.5.31-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/permission-node/CHANGELOG.md b/plugins/permission-node/CHANGELOG.md index 757264e0fd..734a3ebc2f 100644 --- a/plugins/permission-node/CHANGELOG.md +++ b/plugins/permission-node/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-permission-node +## 0.7.19-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-permission-common@0.7.10 + ## 0.7.19-next.1 ### Patch Changes diff --git a/plugins/permission-node/package.json b/plugins/permission-node/package.json index 9e5197f312..5cd6616e18 100644 --- a/plugins/permission-node/package.json +++ b/plugins/permission-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-permission-node", "description": "Common permission and authorization utilities for backend plugins", - "version": "0.7.19-next.1", + "version": "0.7.19-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/playlist-backend/CHANGELOG.md b/plugins/playlist-backend/CHANGELOG.md index 3961855299..a7cde6d097 100644 --- a/plugins/playlist-backend/CHANGELOG.md +++ b/plugins/playlist-backend/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-playlist-backend +## 0.3.12-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-permission-node@0.7.19-next.2 + - @backstage/plugin-playlist-common@0.1.12 + ## 0.3.12-next.1 ### Patch Changes diff --git a/plugins/playlist-backend/package.json b/plugins/playlist-backend/package.json index cc24e9965e..15943da053 100644 --- a/plugins/playlist-backend/package.json +++ b/plugins/playlist-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-playlist-backend", - "version": "0.3.12-next.1", + "version": "0.3.12-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/playlist/CHANGELOG.md b/plugins/playlist/CHANGELOG.md index 477608ee9d..ff6460c029 100644 --- a/plugins/playlist/CHANGELOG.md +++ b/plugins/playlist/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-playlist +## 0.2.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/plugin-search-react@1.7.4-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-catalog-common@1.0.18 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-permission-react@0.4.18-next.1 + - @backstage/plugin-playlist-common@0.1.12 + ## 0.2.2-next.1 ### Patch Changes diff --git a/plugins/playlist/package.json b/plugins/playlist/package.json index 495ab0db5f..af7c76c179 100644 --- a/plugins/playlist/package.json +++ b/plugins/playlist/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-playlist", - "version": "0.2.2-next.1", + "version": "0.2.2-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/proxy-backend/CHANGELOG.md b/plugins/proxy-backend/CHANGELOG.md index c5415d315c..eadc30bec7 100644 --- a/plugins/proxy-backend/CHANGELOG.md +++ b/plugins/proxy-backend/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-proxy-backend +## 0.4.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + ## 0.4.6-next.1 ### Patch Changes diff --git a/plugins/proxy-backend/package.json b/plugins/proxy-backend/package.json index 48da413397..8beddba626 100644 --- a/plugins/proxy-backend/package.json +++ b/plugins/proxy-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-proxy-backend", "description": "A Backstage backend plugin that helps you set up proxy endpoints in the backend", - "version": "0.4.6-next.1", + "version": "0.4.6-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/puppetdb/CHANGELOG.md b/plugins/puppetdb/CHANGELOG.md index c3f622c3bd..01699058c0 100644 --- a/plugins/puppetdb/CHANGELOG.md +++ b/plugins/puppetdb/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-puppetdb +## 0.1.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + ## 0.1.11-next.1 ### Patch Changes diff --git a/plugins/puppetdb/package.json b/plugins/puppetdb/package.json index 639c63c1f7..c54a725356 100644 --- a/plugins/puppetdb/package.json +++ b/plugins/puppetdb/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-puppetdb", "description": "Backstage plugin to visualize resource information and Puppet facts from PuppetDB.", - "version": "0.1.11-next.1", + "version": "0.1.11-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/rollbar-backend/CHANGELOG.md b/plugins/rollbar-backend/CHANGELOG.md index 548bd5cc2d..7df536e3d4 100644 --- a/plugins/rollbar-backend/CHANGELOG.md +++ b/plugins/rollbar-backend/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-rollbar-backend +## 0.1.53-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/config@1.1.1 + ## 0.1.53-next.1 ### Patch Changes diff --git a/plugins/rollbar-backend/package.json b/plugins/rollbar-backend/package.json index 8f352c4ccf..8823d15ff4 100644 --- a/plugins/rollbar-backend/package.json +++ b/plugins/rollbar-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-rollbar-backend", "description": "A Backstage backend plugin that integrates towards Rollbar", - "version": "0.1.53-next.1", + "version": "0.1.53-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/rollbar/CHANGELOG.md b/plugins/rollbar/CHANGELOG.md index 96e3781700..084f3c1a14 100644 --- a/plugins/rollbar/CHANGELOG.md +++ b/plugins/rollbar/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-rollbar +## 0.4.28-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + ## 0.4.28-next.1 ### Patch Changes diff --git a/plugins/rollbar/package.json b/plugins/rollbar/package.json index 3e9b05f360..7c8dd8b9b9 100644 --- a/plugins/rollbar/package.json +++ b/plugins/rollbar/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-rollbar", "description": "A Backstage plugin that integrates towards Rollbar", - "version": "0.4.28-next.1", + "version": "0.4.28-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend-module-confluence-to-markdown/CHANGELOG.md b/plugins/scaffolder-backend-module-confluence-to-markdown/CHANGELOG.md index 838edd9202..2beac8fccb 100644 --- a/plugins/scaffolder-backend-module-confluence-to-markdown/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-confluence-to-markdown/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-scaffolder-backend-module-confluence-to-markdown +## 0.2.9-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.2.9-next.2 + ## 0.2.9-next.1 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-confluence-to-markdown/package.json b/plugins/scaffolder-backend-module-confluence-to-markdown/package.json index 7ffbb59464..48c3fb5aaf 100644 --- a/plugins/scaffolder-backend-module-confluence-to-markdown/package.json +++ b/plugins/scaffolder-backend-module-confluence-to-markdown/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-backend-module-confluence-to-markdown", "description": "The confluence-to-markdown module for @backstage/plugin-scaffolder-backend", - "version": "0.2.9-next.1", + "version": "0.2.9-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md b/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md index 29bace1808..937c6068fe 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-scaffolder-backend-module-cookiecutter +## 0.2.32-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.2.9-next.2 + ## 0.2.32-next.1 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-cookiecutter/package.json b/plugins/scaffolder-backend-module-cookiecutter/package.json index 25b8864b9b..9d99e2ca68 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/package.json +++ b/plugins/scaffolder-backend-module-cookiecutter/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-backend-module-cookiecutter", "description": "A module for the scaffolder backend that lets you template projects using cookiecutter", - "version": "0.2.32-next.1", + "version": "0.2.32-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md b/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md index a9adb44355..b113d4abda 100644 --- a/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-scaffolder-backend-module-gitlab +## 0.2.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/plugin-scaffolder-node@0.2.9-next.2 + ## 0.2.11-next.1 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-gitlab/package.json b/plugins/scaffolder-backend-module-gitlab/package.json index 94641be81c..bdb55606f1 100644 --- a/plugins/scaffolder-backend-module-gitlab/package.json +++ b/plugins/scaffolder-backend-module-gitlab/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-gitlab", - "version": "0.2.11-next.1", + "version": "0.2.11-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend-module-rails/CHANGELOG.md b/plugins/scaffolder-backend-module-rails/CHANGELOG.md index 20538718eb..5df1fe2eef 100644 --- a/plugins/scaffolder-backend-module-rails/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-rails/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-scaffolder-backend-module-rails +## 0.4.25-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.2.9-next.2 + ## 0.4.25-next.1 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-rails/package.json b/plugins/scaffolder-backend-module-rails/package.json index 37f26da084..4a175cffc6 100644 --- a/plugins/scaffolder-backend-module-rails/package.json +++ b/plugins/scaffolder-backend-module-rails/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-backend-module-rails", "description": "A module for the scaffolder backend that lets you template projects using Rails", - "version": "0.4.25-next.1", + "version": "0.4.25-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend-module-sentry/CHANGELOG.md b/plugins/scaffolder-backend-module-sentry/CHANGELOG.md index 70b9b57a6b..47e602cb31 100644 --- a/plugins/scaffolder-backend-module-sentry/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-sentry/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-scaffolder-backend-module-sentry +## 0.1.16-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-scaffolder-node@0.2.9-next.2 + ## 0.1.16-next.1 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-sentry/package.json b/plugins/scaffolder-backend-module-sentry/package.json index c81996bfd6..46dc0c3bba 100644 --- a/plugins/scaffolder-backend-module-sentry/package.json +++ b/plugins/scaffolder-backend-module-sentry/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-sentry", - "version": "0.1.16-next.1", + "version": "0.1.16-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md b/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md index 53389300e2..5715fdb6bd 100644 --- a/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-scaffolder-backend-module-yeoman +## 0.2.29-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.2.9-next.2 + ## 0.2.29-next.1 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-yeoman/package.json b/plugins/scaffolder-backend-module-yeoman/package.json index 6870b60eb9..b05a00598c 100644 --- a/plugins/scaffolder-backend-module-yeoman/package.json +++ b/plugins/scaffolder-backend-module-yeoman/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-yeoman", - "version": "0.2.29-next.1", + "version": "0.2.29-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend/CHANGELOG.md b/plugins/scaffolder-backend/CHANGELOG.md index 30b1516a2d..34dfbbf546 100644 --- a/plugins/scaffolder-backend/CHANGELOG.md +++ b/plugins/scaffolder-backend/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-scaffolder-backend +## 1.19.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/plugin-catalog-backend@1.16.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.5-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.18 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-permission-node@0.7.19-next.2 + - @backstage/plugin-scaffolder-common@1.4.3 + - @backstage/plugin-scaffolder-node@0.2.9-next.2 + ## 1.19.2-next.1 ### Patch Changes diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index f1ea2a3517..b8ee699287 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-backend", "description": "The Backstage backend plugin that helps you create new things", - "version": "1.19.2-next.1", + "version": "1.19.2-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-node/CHANGELOG.md b/plugins/scaffolder-node/CHANGELOG.md index 7dcb041c2f..058c4b0d39 100644 --- a/plugins/scaffolder-node/CHANGELOG.md +++ b/plugins/scaffolder-node/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-scaffolder-node +## 0.2.9-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.4.3 + ## 0.2.9-next.1 ### Patch Changes diff --git a/plugins/scaffolder-node/package.json b/plugins/scaffolder-node/package.json index 5f5702a035..5e939c2ec1 100644 --- a/plugins/scaffolder-node/package.json +++ b/plugins/scaffolder-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-node", "description": "The plugin-scaffolder-node module for @backstage/plugin-scaffolder-backend", - "version": "0.2.9-next.1", + "version": "0.2.9-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-react/CHANGELOG.md b/plugins/scaffolder-react/CHANGELOG.md index b1b2699564..fed5167e92 100644 --- a/plugins/scaffolder-react/CHANGELOG.md +++ b/plugins/scaffolder-react/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-scaffolder-react +## 1.6.2-next.2 + +### Patch Changes + +- 5bb5240: Fixed issue for showing undefined for hidden form items +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-scaffolder-common@1.4.3 + ## 1.6.2-next.1 ### Patch Changes diff --git a/plugins/scaffolder-react/package.json b/plugins/scaffolder-react/package.json index 9849696d19..98af15fb3d 100644 --- a/plugins/scaffolder-react/package.json +++ b/plugins/scaffolder-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-react", "description": "A frontend library that helps other Backstage plugins interact with the Scaffolder", - "version": "1.6.2-next.1", + "version": "1.6.2-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder/CHANGELOG.md b/plugins/scaffolder/CHANGELOG.md index b1a60d6353..60352ac39e 100644 --- a/plugins/scaffolder/CHANGELOG.md +++ b/plugins/scaffolder/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-scaffolder +## 1.16.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/plugin-scaffolder-react@1.6.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/integration-react@1.1.22-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.18 + - @backstage/plugin-permission-react@0.4.18-next.1 + - @backstage/plugin-scaffolder-common@1.4.3 + ## 1.16.2-next.1 ### Patch Changes diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index 13257e2731..63be480b89 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder", "description": "The Backstage plugin that helps you create new things", - "version": "1.16.2-next.1", + "version": "1.16.2-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-backend-module-catalog/CHANGELOG.md b/plugins/search-backend-module-catalog/CHANGELOG.md index 9ea8790218..e997fac742 100644 --- a/plugins/search-backend-module-catalog/CHANGELOG.md +++ b/plugins/search-backend-module-catalog/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-search-backend-module-catalog +## 0.1.12-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-catalog-common@1.0.18 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-search-backend-node@1.2.12-next.2 + - @backstage/plugin-search-common@1.2.8 + ## 0.1.12-next.1 ### Patch Changes diff --git a/plugins/search-backend-module-catalog/package.json b/plugins/search-backend-module-catalog/package.json index d8e78d2fb7..e7a91fe343 100644 --- a/plugins/search-backend-module-catalog/package.json +++ b/plugins/search-backend-module-catalog/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend-module-catalog", "description": "A module for the search backend that exports catalog modules", - "version": "0.1.12-next.1", + "version": "0.1.12-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-backend-module-elasticsearch/CHANGELOG.md b/plugins/search-backend-module-elasticsearch/CHANGELOG.md index 93795174d9..27ac8ba524 100644 --- a/plugins/search-backend-module-elasticsearch/CHANGELOG.md +++ b/plugins/search-backend-module-elasticsearch/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-search-backend-module-elasticsearch +## 1.3.11-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + - @backstage/integration-aws-node@0.1.8 + - @backstage/plugin-search-backend-node@1.2.12-next.2 + - @backstage/plugin-search-common@1.2.8 + ## 1.3.11-next.1 ### Patch Changes diff --git a/plugins/search-backend-module-elasticsearch/package.json b/plugins/search-backend-module-elasticsearch/package.json index 61b26fb5f7..cfcfeee579 100644 --- a/plugins/search-backend-module-elasticsearch/package.json +++ b/plugins/search-backend-module-elasticsearch/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend-module-elasticsearch", "description": "A module for the search backend that implements search using ElasticSearch", - "version": "1.3.11-next.1", + "version": "1.3.11-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-backend-module-explore/CHANGELOG.md b/plugins/search-backend-module-explore/CHANGELOG.md index 01df12e913..1198d21c7f 100644 --- a/plugins/search-backend-module-explore/CHANGELOG.md +++ b/plugins/search-backend-module-explore/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-search-backend-module-explore +## 0.1.12-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/config@1.1.1 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-search-backend-node@1.2.12-next.2 + - @backstage/plugin-search-common@1.2.8 + ## 0.1.12-next.1 ### Patch Changes diff --git a/plugins/search-backend-module-explore/package.json b/plugins/search-backend-module-explore/package.json index e700549839..fb3339928b 100644 --- a/plugins/search-backend-module-explore/package.json +++ b/plugins/search-backend-module-explore/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend-module-explore", "description": "A module for the search backend that exports explore modules", - "version": "0.1.12-next.1", + "version": "0.1.12-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-backend-module-pg/CHANGELOG.md b/plugins/search-backend-module-pg/CHANGELOG.md index 01d5cc175a..7a55a817ca 100644 --- a/plugins/search-backend-module-pg/CHANGELOG.md +++ b/plugins/search-backend-module-pg/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-search-backend-module-pg +## 0.5.17-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + - @backstage/plugin-search-backend-node@1.2.12-next.2 + - @backstage/plugin-search-common@1.2.8 + ## 0.5.17-next.1 ### Patch Changes diff --git a/plugins/search-backend-module-pg/package.json b/plugins/search-backend-module-pg/package.json index 9a0bd19184..a102321a87 100644 --- a/plugins/search-backend-module-pg/package.json +++ b/plugins/search-backend-module-pg/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend-module-pg", "description": "A module for the search backend that implements search using PostgreSQL", - "version": "0.5.17-next.1", + "version": "0.5.17-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md b/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md index f8655cd2d6..b79c9b3928 100644 --- a/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md +++ b/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-search-backend-module-stack-overflow-collator +## 0.1.1-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/config@1.1.1 + - @backstage/plugin-search-backend-node@1.2.12-next.2 + - @backstage/plugin-search-common@1.2.8 + ## 0.1.1-next.1 ### Patch Changes diff --git a/plugins/search-backend-module-stack-overflow-collator/package.json b/plugins/search-backend-module-stack-overflow-collator/package.json index 7863538612..1ec0c9bb0f 100644 --- a/plugins/search-backend-module-stack-overflow-collator/package.json +++ b/plugins/search-backend-module-stack-overflow-collator/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend-module-stack-overflow-collator", "description": "A module for the search backend that exports stack overflow modules", - "version": "0.1.1-next.1", + "version": "0.1.1-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-backend-module-techdocs/CHANGELOG.md b/plugins/search-backend-module-techdocs/CHANGELOG.md index 6f8c0593fc..a6cbf63a2a 100644 --- a/plugins/search-backend-module-techdocs/CHANGELOG.md +++ b/plugins/search-backend-module-techdocs/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-search-backend-module-techdocs +## 0.1.12-next.2 + +### Patch Changes + +- cc4228e: Switched module ID to use kebab-case. +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/plugin-catalog-common@1.0.18 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-search-backend-node@1.2.12-next.2 + - @backstage/plugin-search-common@1.2.8 + - @backstage/plugin-techdocs-node@1.11.0-next.2 + ## 0.1.12-next.1 ### Patch Changes diff --git a/plugins/search-backend-module-techdocs/package.json b/plugins/search-backend-module-techdocs/package.json index 79a027023a..5bf2410430 100644 --- a/plugins/search-backend-module-techdocs/package.json +++ b/plugins/search-backend-module-techdocs/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend-module-techdocs", "description": "A module for the search backend that exports techdocs modules", - "version": "0.1.12-next.1", + "version": "0.1.12-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-backend-node/CHANGELOG.md b/plugins/search-backend-node/CHANGELOG.md index 04a6c06796..096de4cc5c 100644 --- a/plugins/search-backend-node/CHANGELOG.md +++ b/plugins/search-backend-node/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-search-backend-node +## 1.2.12-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-search-common@1.2.8 + ## 1.2.12-next.1 ### Patch Changes diff --git a/plugins/search-backend-node/package.json b/plugins/search-backend-node/package.json index ff561f9754..c1176aa9ba 100644 --- a/plugins/search-backend-node/package.json +++ b/plugins/search-backend-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend-node", "description": "A library for Backstage backend plugins that want to interact with the search backend plugin", - "version": "1.2.12-next.1", + "version": "1.2.12-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-backend/CHANGELOG.md b/plugins/search-backend/CHANGELOG.md index 389ab42a68..aff0014878 100644 --- a/plugins/search-backend/CHANGELOG.md +++ b/plugins/search-backend/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-search-backend +## 1.4.8-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-openapi-utils@0.1.1-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-permission-node@0.7.19-next.2 + - @backstage/plugin-search-backend-node@1.2.12-next.2 + - @backstage/plugin-search-common@1.2.8 + ## 1.4.8-next.1 ### Patch Changes diff --git a/plugins/search-backend/package.json b/plugins/search-backend/package.json index 372aaaae03..8220718ac0 100644 --- a/plugins/search-backend/package.json +++ b/plugins/search-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend", "description": "The Backstage backend plugin that provides your backstage app with search", - "version": "1.4.8-next.1", + "version": "1.4.8-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-react/CHANGELOG.md b/plugins/search-react/CHANGELOG.md index 37b0e72ca4..819ec2d33b 100644 --- a/plugins/search-react/CHANGELOG.md +++ b/plugins/search-react/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-search-react +## 1.7.4-next.2 + +### Patch Changes + +- 36c94b8: Refactor of the alpha exports due to API change in how extension IDs are constructed. +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/theme@0.5.0-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-search-common@1.2.8 + ## 1.7.4-next.1 ### Patch Changes diff --git a/plugins/search-react/package.json b/plugins/search-react/package.json index e007af3b51..fb34895fb1 100644 --- a/plugins/search-react/package.json +++ b/plugins/search-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-react", - "version": "1.7.4-next.1", + "version": "1.7.4-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search/CHANGELOG.md b/plugins/search/CHANGELOG.md index 03f28975c2..bbadde189d 100644 --- a/plugins/search/CHANGELOG.md +++ b/plugins/search/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-search +## 1.4.4-next.3 + +### Patch Changes + +- a1227cc: Wrap `/alpha` export extension elements in backwards compatibility wrapper. +- 8f5d6c1: Updates to the `/alpha` exports to match the extension input wrapping change. +- 36c94b8: Refactor of the alpha exports due to API change in how extension IDs are constructed. +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/theme@0.5.0-next.1 + - @backstage/core-compat-api@0.1.0-next.2 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/plugin-search-react@1.7.4-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-search-common@1.2.8 + ## 1.4.4-next.2 ### Patch Changes diff --git a/plugins/search/package.json b/plugins/search/package.json index da5bbcbd33..33c78cfbc1 100644 --- a/plugins/search/package.json +++ b/plugins/search/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search", "description": "The Backstage plugin that provides your backstage app with search", - "version": "1.4.4-next.2", + "version": "1.4.4-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/sentry/CHANGELOG.md b/plugins/sentry/CHANGELOG.md index 18cd09a846..f6c69ebbc5 100644 --- a/plugins/sentry/CHANGELOG.md +++ b/plugins/sentry/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-sentry +## 0.5.13-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + ## 0.5.13-next.1 ### Patch Changes diff --git a/plugins/sentry/package.json b/plugins/sentry/package.json index aa705c40ca..efd86f5d41 100644 --- a/plugins/sentry/package.json +++ b/plugins/sentry/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-sentry", "description": "A Backstage plugin that integrates towards Sentry", - "version": "0.5.13-next.1", + "version": "0.5.13-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/shortcuts/CHANGELOG.md b/plugins/shortcuts/CHANGELOG.md index 9360aa23a3..3edd1b203c 100644 --- a/plugins/shortcuts/CHANGELOG.md +++ b/plugins/shortcuts/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-shortcuts +## 0.3.17-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/types@1.1.1 + ## 0.3.17-next.1 ### Patch Changes diff --git a/plugins/shortcuts/package.json b/plugins/shortcuts/package.json index 85002ba918..7988358d72 100644 --- a/plugins/shortcuts/package.json +++ b/plugins/shortcuts/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-shortcuts", "description": "A Backstage plugin that provides a shortcuts feature to the sidebar", - "version": "0.3.17-next.1", + "version": "0.3.17-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/sonarqube-backend/CHANGELOG.md b/plugins/sonarqube-backend/CHANGELOG.md index 45fd7abc59..ede6beed67 100644 --- a/plugins/sonarqube-backend/CHANGELOG.md +++ b/plugins/sonarqube-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-sonarqube-backend +## 0.2.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + ## 0.2.10-next.1 ### Patch Changes diff --git a/plugins/sonarqube-backend/package.json b/plugins/sonarqube-backend/package.json index 9959075967..7ce9402edb 100644 --- a/plugins/sonarqube-backend/package.json +++ b/plugins/sonarqube-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-sonarqube-backend", - "version": "0.2.10-next.1", + "version": "0.2.10-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/sonarqube/CHANGELOG.md b/plugins/sonarqube/CHANGELOG.md index d9750032ea..71fa53dae9 100644 --- a/plugins/sonarqube/CHANGELOG.md +++ b/plugins/sonarqube/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-sonarqube +## 0.7.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/plugin-sonarqube-react@0.1.11-next.1 + ## 0.7.10-next.1 ### Patch Changes diff --git a/plugins/sonarqube/package.json b/plugins/sonarqube/package.json index ec8ec3f633..bd94e1c56d 100644 --- a/plugins/sonarqube/package.json +++ b/plugins/sonarqube/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-sonarqube", "description": "", - "version": "0.7.10-next.1", + "version": "0.7.10-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/splunk-on-call/CHANGELOG.md b/plugins/splunk-on-call/CHANGELOG.md index 6b567af287..6aa345e184 100644 --- a/plugins/splunk-on-call/CHANGELOG.md +++ b/plugins/splunk-on-call/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-splunk-on-call +## 0.4.17-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + ## 0.4.17-next.1 ### Patch Changes diff --git a/plugins/splunk-on-call/package.json b/plugins/splunk-on-call/package.json index d612cbbbbd..e481bd469f 100644 --- a/plugins/splunk-on-call/package.json +++ b/plugins/splunk-on-call/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-splunk-on-call", "description": "A Backstage plugin that integrates towards Splunk On-Call", - "version": "0.4.17-next.1", + "version": "0.4.17-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/stack-overflow-backend/CHANGELOG.md b/plugins/stack-overflow-backend/CHANGELOG.md index aec0d6a964..1308080a6d 100644 --- a/plugins/stack-overflow-backend/CHANGELOG.md +++ b/plugins/stack-overflow-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-stack-overflow-backend +## 0.2.12-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.1-next.2 + - @backstage/config@1.1.1 + - @backstage/plugin-search-common@1.2.8 + ## 0.2.12-next.1 ### Patch Changes diff --git a/plugins/stack-overflow-backend/package.json b/plugins/stack-overflow-backend/package.json index 584f9313d2..bbbf1b6a79 100644 --- a/plugins/stack-overflow-backend/package.json +++ b/plugins/stack-overflow-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-stack-overflow-backend", "description": "Deprecated, consider using @backstage/plugin-search-backend-module-stack-overflow-collator instead", - "version": "0.2.12-next.1", + "version": "0.2.12-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/stack-overflow/CHANGELOG.md b/plugins/stack-overflow/CHANGELOG.md index 503462c664..d8d172d0ff 100644 --- a/plugins/stack-overflow/CHANGELOG.md +++ b/plugins/stack-overflow/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-stack-overflow +## 0.1.23-next.2 + +### Patch Changes + +- 36c94b8: Refactor of the alpha exports due to API change in how extension IDs are constructed. +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-search-react@1.7.4-next.2 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/plugin-home-react@0.1.6-next.2 + - @backstage/plugin-search-common@1.2.8 + ## 0.1.23-next.1 ### Patch Changes diff --git a/plugins/stack-overflow/package.json b/plugins/stack-overflow/package.json index 2ec939d18c..8a3501a422 100644 --- a/plugins/stack-overflow/package.json +++ b/plugins/stack-overflow/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-stack-overflow", - "version": "0.1.23-next.1", + "version": "0.1.23-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/stackstorm/CHANGELOG.md b/plugins/stackstorm/CHANGELOG.md index 5a1f4c0d1c..8d10d814a8 100644 --- a/plugins/stackstorm/CHANGELOG.md +++ b/plugins/stackstorm/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-stackstorm +## 0.1.9-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + ## 0.1.9-next.1 ### Patch Changes diff --git a/plugins/stackstorm/package.json b/plugins/stackstorm/package.json index 3a16c66874..95e5606edb 100644 --- a/plugins/stackstorm/package.json +++ b/plugins/stackstorm/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-stackstorm", "description": "A Backstage plugin that integrates towards StackStorm", - "version": "0.1.9-next.1", + "version": "0.1.9-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md b/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md index dd119052ae..b4b09d1d7b 100644 --- a/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md +++ b/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-tech-insights-backend-module-jsonfc +## 0.1.40-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-tech-insights-common@0.2.12 + - @backstage/plugin-tech-insights-node@0.4.14-next.2 + ## 0.1.40-next.1 ### Patch Changes diff --git a/plugins/tech-insights-backend-module-jsonfc/package.json b/plugins/tech-insights-backend-module-jsonfc/package.json index 3fc9d67aed..f78f4f7530 100644 --- a/plugins/tech-insights-backend-module-jsonfc/package.json +++ b/plugins/tech-insights-backend-module-jsonfc/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights-backend-module-jsonfc", - "version": "0.1.40-next.1", + "version": "0.1.40-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/tech-insights-backend/CHANGELOG.md b/plugins/tech-insights-backend/CHANGELOG.md index c80a4ea1d7..d8d3c0f933 100644 --- a/plugins/tech-insights-backend/CHANGELOG.md +++ b/plugins/tech-insights-backend/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-tech-insights-backend +## 0.5.22-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + - @backstage/plugin-tech-insights-node@0.4.14-next.2 + ## 0.5.22-next.1 ### Patch Changes diff --git a/plugins/tech-insights-backend/package.json b/plugins/tech-insights-backend/package.json index 0fbbcf6463..6e446635cb 100644 --- a/plugins/tech-insights-backend/package.json +++ b/plugins/tech-insights-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights-backend", - "version": "0.5.22-next.1", + "version": "0.5.22-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/tech-insights-node/CHANGELOG.md b/plugins/tech-insights-node/CHANGELOG.md index 634b690d9b..36199d726a 100644 --- a/plugins/tech-insights-node/CHANGELOG.md +++ b/plugins/tech-insights-node/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-tech-insights-node +## 0.4.14-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + ## 0.4.14-next.1 ### Patch Changes diff --git a/plugins/tech-insights-node/package.json b/plugins/tech-insights-node/package.json index 8b29e6cceb..c6e6cf2286 100644 --- a/plugins/tech-insights-node/package.json +++ b/plugins/tech-insights-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights-node", - "version": "0.4.14-next.1", + "version": "0.4.14-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/tech-insights/CHANGELOG.md b/plugins/tech-insights/CHANGELOG.md index a73f3dd78e..6c18551001 100644 --- a/plugins/tech-insights/CHANGELOG.md +++ b/plugins/tech-insights/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-tech-insights +## 0.3.20-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + ## 0.3.20-next.1 ### Patch Changes diff --git a/plugins/tech-insights/package.json b/plugins/tech-insights/package.json index 47b0044adb..23445109b0 100644 --- a/plugins/tech-insights/package.json +++ b/plugins/tech-insights/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights", - "version": "0.3.20-next.1", + "version": "0.3.20-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/tech-radar/CHANGELOG.md b/plugins/tech-radar/CHANGELOG.md index b732328bb6..38e4e5a025 100644 --- a/plugins/tech-radar/CHANGELOG.md +++ b/plugins/tech-radar/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-tech-radar +## 0.6.11-next.3 + +### Patch Changes + +- a1227cc: Wrap `/alpha` export extension elements in backwards compatibility wrapper. +- 36c94b8: Refactor of the alpha exports due to API change in how extension IDs are constructed. +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/theme@0.5.0-next.1 + - @backstage/core-compat-api@0.1.0-next.2 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + ## 0.6.11-next.2 ### Patch Changes diff --git a/plugins/tech-radar/package.json b/plugins/tech-radar/package.json index 2fba4121c7..3718e2960a 100644 --- a/plugins/tech-radar/package.json +++ b/plugins/tech-radar/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-tech-radar", "description": "A Backstage plugin that lets you display a Tech Radar for your organization", - "version": "0.6.11-next.2", + "version": "0.6.11-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/techdocs-addons-test-utils/CHANGELOG.md b/plugins/techdocs-addons-test-utils/CHANGELOG.md index 0a5115644e..8a435e5813 100644 --- a/plugins/techdocs-addons-test-utils/CHANGELOG.md +++ b/plugins/techdocs-addons-test-utils/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-techdocs-addons-test-utils +## 1.0.25-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-techdocs@1.9.2-next.3 + - @backstage/plugin-catalog@1.16.0-next.3 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/plugin-search-react@1.7.4-next.2 + - @backstage/core-app-api@1.11.2-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/integration-react@1.1.22-next.1 + - @backstage/test-utils@1.4.6-next.2 + - @backstage/plugin-techdocs-react@1.1.14-next.2 + ## 1.0.25-next.2 ### Patch Changes diff --git a/plugins/techdocs-addons-test-utils/package.json b/plugins/techdocs-addons-test-utils/package.json index 6f334f9ae6..24dcdf042f 100644 --- a/plugins/techdocs-addons-test-utils/package.json +++ b/plugins/techdocs-addons-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-addons-test-utils", - "version": "1.0.25-next.2", + "version": "1.0.25-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/techdocs-backend/CHANGELOG.md b/plugins/techdocs-backend/CHANGELOG.md index a307b1cdbb..d923e0a0e6 100644 --- a/plugins/techdocs-backend/CHANGELOG.md +++ b/plugins/techdocs-backend/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-techdocs-backend +## 1.9.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.1.12-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/plugin-catalog-common@1.0.18 + - @backstage/plugin-permission-common@0.7.10 + - @backstage/plugin-search-common@1.2.8 + - @backstage/plugin-techdocs-node@1.11.0-next.2 + ## 1.9.1-next.1 ### Patch Changes diff --git a/plugins/techdocs-backend/package.json b/plugins/techdocs-backend/package.json index 4f288788a9..80bf7c1bdc 100644 --- a/plugins/techdocs-backend/package.json +++ b/plugins/techdocs-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs-backend", "description": "The Backstage backend plugin that renders technical documentation for your components", - "version": "1.9.1-next.1", + "version": "1.9.1-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/techdocs-module-addons-contrib/CHANGELOG.md b/plugins/techdocs-module-addons-contrib/CHANGELOG.md index cb30015229..852008a4d1 100644 --- a/plugins/techdocs-module-addons-contrib/CHANGELOG.md +++ b/plugins/techdocs-module-addons-contrib/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-techdocs-module-addons-contrib +## 1.1.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/integration@1.8.0-next.1 + - @backstage/integration-react@1.1.22-next.1 + - @backstage/plugin-techdocs-react@1.1.14-next.2 + ## 1.1.3-next.1 ### Patch Changes diff --git a/plugins/techdocs-module-addons-contrib/package.json b/plugins/techdocs-module-addons-contrib/package.json index 231a8c2fa7..2899e1f1ae 100644 --- a/plugins/techdocs-module-addons-contrib/package.json +++ b/plugins/techdocs-module-addons-contrib/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs-module-addons-contrib", "description": "Plugin module for contributed TechDocs Addons", - "version": "1.1.3-next.1", + "version": "1.1.3-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/techdocs-node/CHANGELOG.md b/plugins/techdocs-node/CHANGELOG.md index b2649d492f..5cd95049c6 100644 --- a/plugins/techdocs-node/CHANGELOG.md +++ b/plugins/techdocs-node/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-techdocs-node +## 1.11.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/integration-aws-node@0.1.8 + - @backstage/plugin-search-common@1.2.8 + ## 1.11.0-next.1 ### Patch Changes diff --git a/plugins/techdocs-node/package.json b/plugins/techdocs-node/package.json index 51a18a28bc..31b5f01132 100644 --- a/plugins/techdocs-node/package.json +++ b/plugins/techdocs-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs-node", "description": "Common node.js functionalities for TechDocs, to be shared between techdocs-backend plugin and techdocs-cli", - "version": "1.11.0-next.1", + "version": "1.11.0-next.2", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/plugins/techdocs-react/CHANGELOG.md b/plugins/techdocs-react/CHANGELOG.md index 5c7c768ee2..cd1a166852 100644 --- a/plugins/techdocs-react/CHANGELOG.md +++ b/plugins/techdocs-react/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-techdocs-react +## 1.1.14-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/version-bridge@1.0.7 + ## 1.1.14-next.1 ### Patch Changes diff --git a/plugins/techdocs-react/package.json b/plugins/techdocs-react/package.json index 75d5a67aa3..796dcf6ddc 100644 --- a/plugins/techdocs-react/package.json +++ b/plugins/techdocs-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs-react", "description": "Shared frontend utilities for TechDocs and Addons", - "version": "1.1.14-next.1", + "version": "1.1.14-next.2", "publishConfig": { "access": "public", "main": "dist/index.esm.js", diff --git a/plugins/techdocs/CHANGELOG.md b/plugins/techdocs/CHANGELOG.md index 26794126a7..1a96cdb437 100644 --- a/plugins/techdocs/CHANGELOG.md +++ b/plugins/techdocs/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-techdocs +## 1.9.2-next.3 + +### Patch Changes + +- a1227cc: Wrap `/alpha` export extension elements in backwards compatibility wrapper. +- 36c94b8: Refactor of the alpha exports due to API change in how extension IDs are constructed. +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/theme@0.5.0-next.1 + - @backstage/core-compat-api@0.1.0-next.2 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/plugin-search-react@1.7.4-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/integration-react@1.1.22-next.1 + - @backstage/plugin-search-common@1.2.8 + - @backstage/plugin-techdocs-react@1.1.14-next.2 + ## 1.9.2-next.2 ### Patch Changes diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index 2217c19956..877b9b1f20 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs", "description": "The Backstage plugin that renders technical documentation for your components", - "version": "1.9.2-next.2", + "version": "1.9.2-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/todo-backend/CHANGELOG.md b/plugins/todo-backend/CHANGELOG.md index c2a25854d6..7ec5dfae85 100644 --- a/plugins/todo-backend/CHANGELOG.md +++ b/plugins/todo-backend/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-todo-backend +## 0.3.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.0-next.2 + - @backstage/backend-common@0.20.0-next.2 + - @backstage/catalog-client@1.5.0-next.1 + - @backstage/backend-openapi-utils@0.1.1-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + ## 0.3.6-next.1 ### Patch Changes diff --git a/plugins/todo-backend/package.json b/plugins/todo-backend/package.json index 2d33b028ca..bc69fbb57e 100644 --- a/plugins/todo-backend/package.json +++ b/plugins/todo-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-todo-backend", "description": "A Backstage backend plugin that lets you browse TODO comments in your source code", - "version": "0.3.6-next.1", + "version": "0.3.6-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/todo/CHANGELOG.md b/plugins/todo/CHANGELOG.md index 260e669324..2c19eb2e3e 100644 --- a/plugins/todo/CHANGELOG.md +++ b/plugins/todo/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-todo +## 0.2.32-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + ## 0.2.32-next.1 ### Patch Changes diff --git a/plugins/todo/package.json b/plugins/todo/package.json index 8df6781fb1..12deedde5b 100644 --- a/plugins/todo/package.json +++ b/plugins/todo/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-todo", "description": "A Backstage plugin that lets you browse TODO comments in your source code", - "version": "0.2.32-next.1", + "version": "0.2.32-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/user-settings-backend/CHANGELOG.md b/plugins/user-settings-backend/CHANGELOG.md index 8158c2681d..3794e7e9fd 100644 --- a/plugins/user-settings-backend/CHANGELOG.md +++ b/plugins/user-settings-backend/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-user-settings-backend +## 0.2.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/plugin-auth-node@0.4.2-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + ## 0.2.7-next.1 ### Patch Changes diff --git a/plugins/user-settings-backend/package.json b/plugins/user-settings-backend/package.json index 3bbbf6a2be..c683f0ff2e 100644 --- a/plugins/user-settings-backend/package.json +++ b/plugins/user-settings-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-user-settings-backend", "description": "The Backstage backend plugin to manage user settings", - "version": "0.2.7-next.1", + "version": "0.2.7-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/user-settings/CHANGELOG.md b/plugins/user-settings/CHANGELOG.md index 1cbc748245..899cf92da7 100644 --- a/plugins/user-settings/CHANGELOG.md +++ b/plugins/user-settings/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-user-settings +## 0.7.14-next.3 + +### Patch Changes + +- a1227cc: Wrap `/alpha` export extension elements in backwards compatibility wrapper. +- 8f5d6c1: Updates to the `/alpha` exports to match the extension input wrapping change. +- 36c94b8: Refactor of the alpha exports due to API change in how extension IDs are constructed. +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/theme@0.5.0-next.1 + - @backstage/core-compat-api@0.1.0-next.2 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/core-app-api@1.11.2-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + ## 0.7.14-next.2 ### Patch Changes diff --git a/plugins/user-settings/package.json b/plugins/user-settings/package.json index c25cff5ede..ba26c62098 100644 --- a/plugins/user-settings/package.json +++ b/plugins/user-settings/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-user-settings", "description": "A Backstage plugin that provides a settings page", - "version": "0.7.14-next.2", + "version": "0.7.14-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/vault-backend/CHANGELOG.md b/plugins/vault-backend/CHANGELOG.md index ccbf0d4030..3eddc7b59a 100644 --- a/plugins/vault-backend/CHANGELOG.md +++ b/plugins/vault-backend/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-vault-backend +## 0.4.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/backend-plugin-api@0.6.8-next.2 + - @backstage/backend-tasks@0.5.13-next.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-vault-node@0.1.1-next.2 + ## 0.4.1-next.1 ### Patch Changes diff --git a/plugins/vault-backend/package.json b/plugins/vault-backend/package.json index 82420b5493..1cf88d376d 100644 --- a/plugins/vault-backend/package.json +++ b/plugins/vault-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-vault-backend", "description": "A Backstage backend plugin that integrates towards Vault", - "version": "0.4.1-next.1", + "version": "0.4.1-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/vault-node/CHANGELOG.md b/plugins/vault-node/CHANGELOG.md index 794c570555..a611bd6a83 100644 --- a/plugins/vault-node/CHANGELOG.md +++ b/plugins/vault-node/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-vault-node +## 0.1.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.8-next.2 + ## 0.1.1-next.1 ### Patch Changes diff --git a/plugins/vault-node/package.json b/plugins/vault-node/package.json index b8ccb98ce3..da57ba0345 100644 --- a/plugins/vault-node/package.json +++ b/plugins/vault-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-vault-node", "description": "Node.js library for the vault plugin", - "version": "0.1.1-next.1", + "version": "0.1.1-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/vault/CHANGELOG.md b/plugins/vault/CHANGELOG.md index b1a30d0111..8200b7cf47 100644 --- a/plugins/vault/CHANGELOG.md +++ b/plugins/vault/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-vault +## 0.1.23-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + ## 0.1.23-next.1 ### Patch Changes diff --git a/plugins/vault/package.json b/plugins/vault/package.json index 9374be54ec..9bf7f2ed4a 100644 --- a/plugins/vault/package.json +++ b/plugins/vault/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-vault", "description": "A Backstage plugin that integrates towards Vault", - "version": "0.1.23-next.1", + "version": "0.1.23-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/xcmetrics/CHANGELOG.md b/plugins/xcmetrics/CHANGELOG.md index a1aacf43a0..67c05b52af 100644 --- a/plugins/xcmetrics/CHANGELOG.md +++ b/plugins/xcmetrics/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-xcmetrics +## 0.2.46-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.0-next.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + ## 0.2.46-next.1 ### Patch Changes diff --git a/plugins/xcmetrics/package.json b/plugins/xcmetrics/package.json index 516c609b7a..9a17200571 100644 --- a/plugins/xcmetrics/package.json +++ b/plugins/xcmetrics/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-xcmetrics", "description": "A Backstage plugin that shows XCode build metrics for your components", - "version": "0.2.46-next.1", + "version": "0.2.46-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", From e9fd482c469735db24a42c49f81d10a1dd4d2988 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Dec 2023 00:11:56 +0000 Subject: [PATCH 079/275] chore(deps): Bump vite from 4.5.0 to 4.5.1 Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 4.5.0 to 4.5.1. - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/v4.5.1/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v4.5.1/packages/vite) --- updated-dependencies: - dependency-name: vite dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 9c724386dc..630c145f75 100644 --- a/yarn.lock +++ b/yarn.lock @@ -44247,8 +44247,8 @@ __metadata: linkType: hard "vite@npm:^4.4.9": - version: 4.5.0 - resolution: "vite@npm:4.5.0" + version: 4.5.1 + resolution: "vite@npm:4.5.1" dependencies: esbuild: ^0.18.10 fsevents: ~2.3.2 @@ -44282,7 +44282,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 06f1a4c858e4dc4c04a10466f4ccacea30c5a9f8574e5ba3deb9d03fa20e80ca6797f02dad97a988da7cdef96238dbc69c3b6a538156585c74722d996223619e + checksum: 72b3584b3d3b8d14e8a37f0248e47fb8b4d02ab35de5b5a8e5ca8ae55c3be2aab73760dc36edac4fa722de182f78cc492eb44888fcb4a9a0712c4605dad644f9 languageName: node linkType: hard From e6861646f81f7cbff747f785daa37d8f439ea7a2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Dec 2023 01:07:33 +0000 Subject: [PATCH 080/275] chore(deps): update dependency vite to v4.5.1 [security] Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 9c724386dc..630c145f75 100644 --- a/yarn.lock +++ b/yarn.lock @@ -44247,8 +44247,8 @@ __metadata: linkType: hard "vite@npm:^4.4.9": - version: 4.5.0 - resolution: "vite@npm:4.5.0" + version: 4.5.1 + resolution: "vite@npm:4.5.1" dependencies: esbuild: ^0.18.10 fsevents: ~2.3.2 @@ -44282,7 +44282,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 06f1a4c858e4dc4c04a10466f4ccacea30c5a9f8574e5ba3deb9d03fa20e80ca6797f02dad97a988da7cdef96238dbc69c3b6a538156585c74722d996223619e + checksum: 72b3584b3d3b8d14e8a37f0248e47fb8b4d02ab35de5b5a8e5ca8ae55c3be2aab73760dc36edac4fa722de182f78cc492eb44888fcb4a9a0712c4605dad644f9 languageName: node linkType: hard From 027568a81900fa29785ddbf81f3b256784844601 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Dec 2023 08:08:02 +0000 Subject: [PATCH 081/275] chore(deps): update dependency @types/diff to v5.0.9 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 630c145f75..90523207ce 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18047,9 +18047,9 @@ __metadata: linkType: hard "@types/diff@npm:^5.0.0": - version: 5.0.8 - resolution: "@types/diff@npm:5.0.8" - checksum: 729c74c408905cb88ae7a8245e8c1d03359f2c01168beee4d90304af1cdf99462e4a1f2c49b3a64e27623baae3ea7a5a8f883b1db5a3ec075770700a14ad0904 + version: 5.0.9 + resolution: "@types/diff@npm:5.0.9" + checksum: fb5cb6d6407e3ebcd8883bdc9f9124b57ebc04720cfb605afc5f839f9a71878ccf895da66b09d5d8df25e684cfe57a6f6f4bf65f87ccc0ce0b58a18b1f3ce5b0 languageName: node linkType: hard From 6efa44920b6c1ea755ef0fc80caf731695ec9502 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Dec 2023 08:16:17 +0000 Subject: [PATCH 082/275] chore(deps): update dependency @types/jest to v29.5.11 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 630c145f75..60413ffeae 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18366,12 +18366,12 @@ __metadata: linkType: hard "@types/jest@npm:*, @types/jest@npm:^29.0.0": - version: 29.5.10 - resolution: "@types/jest@npm:29.5.10" + version: 29.5.11 + resolution: "@types/jest@npm:29.5.11" dependencies: expect: ^29.0.0 pretty-format: ^29.0.0 - checksum: ef385905787db528de9b6beb2688865c0bb276e64256ed60b9a1a6ffc0b75737456cb5e27e952a3241c5845b6a1da487470010dd30f3ca59c8581624c564a823 + checksum: f892a06ec9f0afa9a61cd7fa316ec614e21d4df1ad301b5a837787e046fcb40dfdf7f264a55e813ac6b9b633cb9d366bd5b8d1cea725e84102477b366df23fdd languageName: node linkType: hard From ae0808de90e45626a4ee7a9dcd4351d3b40c43cf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Dec 2023 09:09:06 +0000 Subject: [PATCH 083/275] chore(deps): update dependency @types/luxon to v3.3.7 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- microsite/yarn.lock | 6 +++--- yarn.lock | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/microsite/yarn.lock b/microsite/yarn.lock index 6df5247272..cb53446657 100644 --- a/microsite/yarn.lock +++ b/microsite/yarn.lock @@ -3045,9 +3045,9 @@ __metadata: linkType: hard "@types/luxon@npm:^3.0.0": - version: 3.3.6 - resolution: "@types/luxon@npm:3.3.6" - checksum: 44fd3e617fb5d9e370a8d5529de3e703b295bfe225936e786e0b5e7fce662ef82012a6ec29cd2763afbd59bf9a9ab43186bad5c51aa552d963cd5e8c8f4e1d4f + version: 3.3.7 + resolution: "@types/luxon@npm:3.3.7" + checksum: 97026557e92bcba308a5592f981591cd200d493fc8997874d79acecf6a2ec41debeded3ac5cd80c371ef7f6f56cc0d1be0a5aca846e03d3e6b4a2be37256fe2f languageName: node linkType: hard diff --git a/yarn.lock b/yarn.lock index 790655e858..cab922a020 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18500,9 +18500,9 @@ __metadata: linkType: hard "@types/luxon@npm:*, @types/luxon@npm:^3.0.0, @types/luxon@npm:~3.3.0": - version: 3.3.6 - resolution: "@types/luxon@npm:3.3.6" - checksum: 44fd3e617fb5d9e370a8d5529de3e703b295bfe225936e786e0b5e7fce662ef82012a6ec29cd2763afbd59bf9a9ab43186bad5c51aa552d963cd5e8c8f4e1d4f + version: 3.3.7 + resolution: "@types/luxon@npm:3.3.7" + checksum: 97026557e92bcba308a5592f981591cd200d493fc8997874d79acecf6a2ec41debeded3ac5cd80c371ef7f6f56cc0d1be0a5aca846e03d3e6b4a2be37256fe2f languageName: node linkType: hard From 8ecb0b9a20e090af6a462c51ab3f773fd3ddad5f Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 6 Dec 2023 12:31:05 +0100 Subject: [PATCH 084/275] chore: created github module Signed-off-by: blam --- .../.eslintrc.js | 1 + .../README.md | 5 + .../package.json | 49 ++++++ .../src/actions/gitHelpers.ts | 143 ++++++++++++++++++ .../actions}/gitHubEnvironment.examples.ts | 0 .../src/actions}/github.examples.test.ts | 28 +++- .../src/actions}/github.examples.ts | 0 .../src/actions}/github.test.ts | 28 +++- .../src/actions}/github.ts | 12 +- .../githubActionsDispatch.examples.test.ts | 0 .../githubActionsDispatch.examples.ts | 0 .../actions}/githubActionsDispatch.test.ts | 0 .../src/actions}/githubActionsDispatch.ts | 6 +- .../actions}/githubDeployKey.examples.test.ts | 0 .../src/actions}/githubDeployKey.examples.ts | 0 .../src/actions}/githubDeployKey.test.ts | 0 .../src/actions}/githubDeployKey.ts | 6 +- .../githubEnvironment.examples.test.ts | 0 .../src/actions}/githubEnvironment.test.ts | 0 .../src/actions}/githubEnvironment.ts | 6 +- .../githubIssuesLabel.examples.test.ts | 0 .../actions}/githubIssuesLabel.examples.ts | 0 .../src/actions}/githubIssuesLabel.test.ts | 0 .../src/actions}/githubIssuesLabel.ts | 6 +- .../githubPullRequest.examples.test.ts | 0 .../actions}/githubPullRequest.examples.ts | 0 .../src/actions}/githubPullRequest.test.ts | 0 .../src/actions}/githubPullRequest.ts | 14 +- .../githubRepoCreate.examples.test.ts | 9 +- .../src/actions}/githubRepoCreate.examples.ts | 0 .../src/actions}/githubRepoCreate.test.ts | 9 +- .../src/actions}/githubRepoCreate.ts | 6 +- .../actions}/githubRepoPush.examples.test.ts | 26 +++- .../src/actions}/githubRepoPush.examples.ts | 0 .../src/actions}/githubRepoPush.test.ts | 30 +++- .../src/actions}/githubRepoPush.ts | 6 +- .../actions}/githubWebhook.examples.test.ts | 0 .../src/actions}/githubWebhook.examples.ts | 0 .../src/actions}/githubWebhook.test.ts | 0 .../src/actions}/githubWebhook.ts | 6 +- .../src/actions}/helpers.ts | 24 ++- .../src/actions}/index.ts | 3 + .../src/actions}/inputProperties.ts | 0 .../src/actions}/outputProperties.ts | 0 .../src/index.ts | 23 +++ 45 files changed, 393 insertions(+), 53 deletions(-) create mode 100644 plugins/scaffolder-backend-module-github/.eslintrc.js create mode 100644 plugins/scaffolder-backend-module-github/README.md create mode 100644 plugins/scaffolder-backend-module-github/package.json create mode 100644 plugins/scaffolder-backend-module-github/src/actions/gitHelpers.ts rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/github => scaffolder-backend-module-github/src/actions}/gitHubEnvironment.examples.ts (100%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/publish => scaffolder-backend-module-github/src/actions}/github.examples.test.ts (85%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/publish => scaffolder-backend-module-github/src/actions}/github.examples.ts (100%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/publish => scaffolder-backend-module-github/src/actions}/github.test.ts (98%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/publish => scaffolder-backend-module-github/src/actions}/github.ts (97%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/github => scaffolder-backend-module-github/src/actions}/githubActionsDispatch.examples.test.ts (100%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/github => scaffolder-backend-module-github/src/actions}/githubActionsDispatch.examples.ts (100%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/github => scaffolder-backend-module-github/src/actions}/githubActionsDispatch.test.ts (100%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/github => scaffolder-backend-module-github/src/actions}/githubActionsDispatch.ts (96%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/github => scaffolder-backend-module-github/src/actions}/githubDeployKey.examples.test.ts (100%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/github => scaffolder-backend-module-github/src/actions}/githubDeployKey.examples.ts (100%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/github => scaffolder-backend-module-github/src/actions}/githubDeployKey.test.ts (100%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/github => scaffolder-backend-module-github/src/actions}/githubDeployKey.ts (97%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/github => scaffolder-backend-module-github/src/actions}/githubEnvironment.examples.test.ts (100%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/github => scaffolder-backend-module-github/src/actions}/githubEnvironment.test.ts (100%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/github => scaffolder-backend-module-github/src/actions}/githubEnvironment.ts (98%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/github => scaffolder-backend-module-github/src/actions}/githubIssuesLabel.examples.test.ts (100%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/github => scaffolder-backend-module-github/src/actions}/githubIssuesLabel.examples.ts (100%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/github => scaffolder-backend-module-github/src/actions}/githubIssuesLabel.test.ts (100%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/github => scaffolder-backend-module-github/src/actions}/githubIssuesLabel.ts (96%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/publish => scaffolder-backend-module-github/src/actions}/githubPullRequest.examples.test.ts (100%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/publish => scaffolder-backend-module-github/src/actions}/githubPullRequest.examples.ts (100%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/publish => scaffolder-backend-module-github/src/actions}/githubPullRequest.test.ts (100%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/publish => scaffolder-backend-module-github/src/actions}/githubPullRequest.ts (98%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/github => scaffolder-backend-module-github/src/actions}/githubRepoCreate.examples.test.ts (96%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/github => scaffolder-backend-module-github/src/actions}/githubRepoCreate.examples.ts (100%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/github => scaffolder-backend-module-github/src/actions}/githubRepoCreate.test.ts (99%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/github => scaffolder-backend-module-github/src/actions}/githubRepoCreate.ts (98%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/github => scaffolder-backend-module-github/src/actions}/githubRepoPush.examples.test.ts (85%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/github => scaffolder-backend-module-github/src/actions}/githubRepoPush.examples.ts (100%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/github => scaffolder-backend-module-github/src/actions}/githubRepoPush.test.ts (96%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/github => scaffolder-backend-module-github/src/actions}/githubRepoPush.ts (98%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/github => scaffolder-backend-module-github/src/actions}/githubWebhook.examples.test.ts (100%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/github => scaffolder-backend-module-github/src/actions}/githubWebhook.examples.ts (100%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/github => scaffolder-backend-module-github/src/actions}/githubWebhook.test.ts (100%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/github => scaffolder-backend-module-github/src/actions}/githubWebhook.ts (97%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/github => scaffolder-backend-module-github/src/actions}/helpers.ts (97%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/github => scaffolder-backend-module-github/src/actions}/index.ts (89%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/github => scaffolder-backend-module-github/src/actions}/inputProperties.ts (100%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/github => scaffolder-backend-module-github/src/actions}/outputProperties.ts (100%) create mode 100644 plugins/scaffolder-backend-module-github/src/index.ts diff --git a/plugins/scaffolder-backend-module-github/.eslintrc.js b/plugins/scaffolder-backend-module-github/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/scaffolder-backend-module-github/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/scaffolder-backend-module-github/README.md b/plugins/scaffolder-backend-module-github/README.md new file mode 100644 index 0000000000..ba4b3a8787 --- /dev/null +++ b/plugins/scaffolder-backend-module-github/README.md @@ -0,0 +1,5 @@ +# @backstage/plugin-scaffolder-backend-module-github + +The github module for [@backstage/plugin-scaffolder-backend](https://www.npmjs.com/package/@backstage/plugin-scaffolder-backend). + +_This plugin was created through the Backstage CLI_ diff --git a/plugins/scaffolder-backend-module-github/package.json b/plugins/scaffolder-backend-module-github/package.json new file mode 100644 index 0000000000..9779ea8040 --- /dev/null +++ b/plugins/scaffolder-backend-module-github/package.json @@ -0,0 +1,49 @@ +{ + "name": "@backstage/plugin-scaffolder-backend-module-github", + "description": "The github module for @backstage/plugin-scaffolder-backend", + "version": "0.0.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "backend-plugin-module" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/backend-common": "workspace:^", + "@backstage/config": "workspace:^", + "@backstage/errors": "workspace:^", + "@backstage/integration": "workspace:^", + "@backstage/plugin-scaffolder-node": "workspace:^", + "@octokit/webhooks": "^10.0.0", + "libsodium-wrappers": "^0.7.11", + "octokit": "^2.0.0", + "octokit-plugin-create-pull-request": "^3.10.0", + "winston": "^3.2.1", + "yaml": "^2.0.0" + }, + "devDependencies": { + "@backstage/backend-test-utils": "workspace:^", + "@backstage/cli": "workspace:^", + "@types/libsodium-wrappers": "^0.7.10", + "fs-extra": "10.1.0", + "jest-when": "^3.1.0", + "jsonschema": "^1.2.6" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/scaffolder-backend-module-github/src/actions/gitHelpers.ts b/plugins/scaffolder-backend-module-github/src/actions/gitHelpers.ts new file mode 100644 index 0000000000..f94cf1e71c --- /dev/null +++ b/plugins/scaffolder-backend-module-github/src/actions/gitHelpers.ts @@ -0,0 +1,143 @@ +/* + * 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 { Config } from '@backstage/config'; +import { assertError } from '@backstage/errors'; +import { Octokit } from 'octokit'; +import { Logger } from 'winston'; + +type BranchProtectionOptions = { + client: Octokit; + owner: string; + repoName: string; + logger: Logger; + requireCodeOwnerReviews: boolean; + requiredStatusCheckContexts?: string[]; + bypassPullRequestAllowances?: { + users?: string[]; + teams?: string[]; + apps?: string[]; + }; + requiredApprovingReviewCount?: number; + restrictions?: { + users: string[]; + teams: string[]; + apps?: string[]; + }; + requireBranchesToBeUpToDate?: boolean; + requiredConversationResolution?: boolean; + defaultBranch?: string; + enforceAdmins?: boolean; + dismissStaleReviews?: boolean; + requiredCommitSigning?: boolean; +}; + +export const enableBranchProtectionOnDefaultRepoBranch = async ({ + repoName, + client, + owner, + logger, + requireCodeOwnerReviews, + bypassPullRequestAllowances, + requiredApprovingReviewCount, + restrictions, + requiredStatusCheckContexts = [], + requireBranchesToBeUpToDate = true, + requiredConversationResolution = false, + defaultBranch = 'master', + enforceAdmins = true, + dismissStaleReviews = false, + requiredCommitSigning = false, +}: BranchProtectionOptions): Promise => { + const tryOnce = async () => { + try { + await client.rest.repos.updateBranchProtection({ + mediaType: { + /** + * 👇 we need this preview because allowing a custom + * reviewer count on branch protection is a preview + * feature + * + * More here: https://docs.github.com/en/rest/overview/api-previews#require-multiple-approving-reviews + */ + previews: ['luke-cage-preview'], + }, + owner, + repo: repoName, + branch: defaultBranch, + required_status_checks: { + strict: requireBranchesToBeUpToDate, + contexts: requiredStatusCheckContexts, + }, + restrictions: restrictions ?? null, + enforce_admins: enforceAdmins, + required_pull_request_reviews: { + required_approving_review_count: requiredApprovingReviewCount, + require_code_owner_reviews: requireCodeOwnerReviews, + bypass_pull_request_allowances: bypassPullRequestAllowances, + dismiss_stale_reviews: dismissStaleReviews, + }, + required_conversation_resolution: requiredConversationResolution, + }); + + if (requiredCommitSigning) { + await client.rest.repos.createCommitSignatureProtection({ + owner, + repo: repoName, + branch: defaultBranch, + }); + } + } catch (e) { + assertError(e); + if ( + e.message.includes( + 'Upgrade to GitHub Pro or make this repository public to enable this feature', + ) + ) { + logger.warn( + 'Branch protection was not enabled as it requires GitHub Pro for private repositories', + ); + } else { + throw e; + } + } + }; + + try { + await tryOnce(); + } catch (e) { + if (!e.message.includes('Branch not found')) { + throw e; + } + + // GitHub has eventual consistency. Fail silently, wait, and try again. + await new Promise(resolve => setTimeout(resolve, 600)); + await tryOnce(); + } +}; + +export function getGitCommitMessage( + gitCommitMessage: string | undefined, + config: Config, +): string | undefined { + return gitCommitMessage + ? gitCommitMessage + : config.getOptionalString('scaffolder.defaultCommitMessage'); +} + +export function entityRefToName(name: string): string { + return name.replace(/^.*[:/]/g, ''); +} diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/gitHubEnvironment.examples.ts b/plugins/scaffolder-backend-module-github/src/actions/gitHubEnvironment.examples.ts similarity index 100% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/gitHubEnvironment.examples.ts rename to plugins/scaffolder-backend-module-github/src/actions/gitHubEnvironment.examples.ts diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.examples.test.ts b/plugins/scaffolder-backend-module-github/src/actions/github.examples.test.ts similarity index 85% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.examples.test.ts rename to plugins/scaffolder-backend-module-github/src/actions/github.examples.test.ts index 4d87ec97c4..7ea5e025ce 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.examples.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/github.examples.test.ts @@ -13,9 +13,29 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -jest.mock('../helpers'); +jest.mock('./gitHelpers', () => { + return { + ...jest.requireActual('./gitHelpers'), + entityRefToName: jest.fn(), + }; +}); -import { TemplateAction } from '@backstage/plugin-scaffolder-node'; +jest.mock('@backstage/plugin-scaffolder-node', () => { + return { + ...jest.requireActual('@backstage/plugin-scaffolder-node'), + initRepoAndPush: jest.fn().mockResolvedValue({ + commitHash: '220f19cc36b551763d157f1b5e4a4b446165dbd6', + }), + commitAndPushRepo: jest.fn().mockResolvedValue({ + commitHash: '220f19cc36b551763d157f1b5e4a4b446165dbd6', + }), + }; +}); + +import { + TemplateAction, + initRepoAndPush, +} from '@backstage/plugin-scaffolder-node'; import { getVoidLogger } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; import { @@ -24,10 +44,10 @@ import { ScmIntegrations, } from '@backstage/integration'; import { PassThrough } from 'stream'; -import { entityRefToName, initRepoAndPush } from '../helpers'; import { createPublishGithubAction } from './github'; import { examples } from './github.examples'; import yaml from 'yaml'; +import { entityRefToName } from './gitHelpers'; const publicKey = '2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvvcCU='; @@ -76,7 +96,7 @@ describe('publish:github', () => { }); const { entityRefToName: realFamiliarizeEntityName } = - jest.requireActual('../helpers'); + jest.requireActual('./helpers'); const integrations = ScmIntegrations.fromConfig(config); let githubCredentialsProvider: GithubCredentialsProvider; let action: TemplateAction; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.examples.ts b/plugins/scaffolder-backend-module-github/src/actions/github.examples.ts similarity index 100% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.examples.ts rename to plugins/scaffolder-backend-module-github/src/actions/github.examples.ts diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.test.ts b/plugins/scaffolder-backend-module-github/src/actions/github.test.ts similarity index 98% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.test.ts rename to plugins/scaffolder-backend-module-github/src/actions/github.test.ts index e15d085cbf..c22d8ca7c3 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/github.test.ts @@ -13,7 +13,25 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -jest.mock('../helpers'); +jest.mock('./gitHelpers', () => { + return { + ...jest.requireActual('./gitHelpers'), + enableBranchProtectionOnDefaultRepoBranch: jest.fn(), + entityRefToName: jest.fn(), + }; +}); + +jest.mock('@backstage/plugin-scaffolder-node', () => { + return { + ...jest.requireActual('@backstage/plugin-scaffolder-node'), + initRepoAndPush: jest.fn().mockResolvedValue({ + commitHash: '220f19cc36b551763d157f1b5e4a4b446165dbd6', + }), + commitAndPushRepo: jest.fn().mockResolvedValue({ + commitHash: '220f19cc36b551763d157f1b5e4a4b446165dbd6', + }), + }; +}); import { TemplateAction } from '@backstage/plugin-scaffolder-node'; import { getVoidLogger } from '@backstage/backend-common'; @@ -25,12 +43,12 @@ import { } from '@backstage/integration'; import { when } from 'jest-when'; import { PassThrough } from 'stream'; +import { createPublishGithubAction } from './github'; +import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; import { enableBranchProtectionOnDefaultRepoBranch, entityRefToName, - initRepoAndPush, -} from '../helpers'; -import { createPublishGithubAction } from './github'; +} from './gitHelpers'; const publicKey = '2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvvcCU='; @@ -79,7 +97,7 @@ describe('publish:github', () => { }); const { entityRefToName: realFamiliarizeEntityName } = - jest.requireActual('../helpers'); + jest.requireActual('./gitHelpers'); const integrations = ScmIntegrations.fromConfig(config); let githubCredentialsProvider: GithubCredentialsProvider; let action: TemplateAction; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.ts b/plugins/scaffolder-backend-module-github/src/actions/github.ts similarity index 97% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.ts rename to plugins/scaffolder-backend-module-github/src/actions/github.ts index e5b6071863..62f657b01c 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/github.ts @@ -21,15 +21,17 @@ import { ScmIntegrationRegistry, } from '@backstage/integration'; import { Octokit } from 'octokit'; -import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; +import { + createTemplateAction, + parseRepoUrl, +} from '@backstage/plugin-scaffolder-node'; import { createGithubRepoWithCollaboratorsAndTopics, getOctokitOptions, initRepoPushAndProtect, -} from '../github/helpers'; -import * as inputProps from '../github/inputProperties'; -import * as outputProps from '../github/outputProperties'; -import { parseRepoUrl } from './util'; +} from './helpers'; +import * as inputProps from './inputProperties'; +import * as outputProps from './outputProperties'; import { examples } from './github.examples'; /** diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubActionsDispatch.examples.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubActionsDispatch.examples.test.ts similarity index 100% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubActionsDispatch.examples.test.ts rename to plugins/scaffolder-backend-module-github/src/actions/githubActionsDispatch.examples.test.ts diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubActionsDispatch.examples.ts b/plugins/scaffolder-backend-module-github/src/actions/githubActionsDispatch.examples.ts similarity index 100% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubActionsDispatch.examples.ts rename to plugins/scaffolder-backend-module-github/src/actions/githubActionsDispatch.examples.ts diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubActionsDispatch.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubActionsDispatch.test.ts similarity index 100% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubActionsDispatch.test.ts rename to plugins/scaffolder-backend-module-github/src/actions/githubActionsDispatch.test.ts diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubActionsDispatch.ts b/plugins/scaffolder-backend-module-github/src/actions/githubActionsDispatch.ts similarity index 96% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubActionsDispatch.ts rename to plugins/scaffolder-backend-module-github/src/actions/githubActionsDispatch.ts index 6623ee1f27..0d24b74927 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubActionsDispatch.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubActionsDispatch.ts @@ -19,9 +19,11 @@ import { GithubCredentialsProvider, ScmIntegrations, } from '@backstage/integration'; -import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; +import { + createTemplateAction, + parseRepoUrl, +} from '@backstage/plugin-scaffolder-node'; import { Octokit } from 'octokit'; -import { parseRepoUrl } from '../publish/util'; import { getOctokitOptions } from './helpers'; import { examples } from './githubActionsDispatch.examples'; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubDeployKey.examples.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubDeployKey.examples.test.ts similarity index 100% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubDeployKey.examples.test.ts rename to plugins/scaffolder-backend-module-github/src/actions/githubDeployKey.examples.test.ts diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubDeployKey.examples.ts b/plugins/scaffolder-backend-module-github/src/actions/githubDeployKey.examples.ts similarity index 100% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubDeployKey.examples.ts rename to plugins/scaffolder-backend-module-github/src/actions/githubDeployKey.examples.ts diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubDeployKey.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubDeployKey.test.ts similarity index 100% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubDeployKey.test.ts rename to plugins/scaffolder-backend-module-github/src/actions/githubDeployKey.test.ts diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubDeployKey.ts b/plugins/scaffolder-backend-module-github/src/actions/githubDeployKey.ts similarity index 97% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubDeployKey.ts rename to plugins/scaffolder-backend-module-github/src/actions/githubDeployKey.ts index 1db9746bb4..ba55b6a1fb 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubDeployKey.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubDeployKey.ts @@ -15,9 +15,11 @@ */ import { InputError } from '@backstage/errors'; -import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; +import { + createTemplateAction, + parseRepoUrl, +} from '@backstage/plugin-scaffolder-node'; import { ScmIntegrationRegistry } from '@backstage/integration'; -import { parseRepoUrl } from '../publish/util'; import { getOctokitOptions } from './helpers'; import { Octokit } from 'octokit'; import Sodium from 'libsodium-wrappers'; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubEnvironment.examples.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.examples.test.ts similarity index 100% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubEnvironment.examples.test.ts rename to plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.examples.test.ts diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubEnvironment.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.test.ts similarity index 100% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubEnvironment.test.ts rename to plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.test.ts diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubEnvironment.ts b/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.ts similarity index 98% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubEnvironment.ts rename to plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.ts index 16859d9a26..7f6f9f7fa3 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubEnvironment.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.ts @@ -15,9 +15,11 @@ */ import { InputError } from '@backstage/errors'; -import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; +import { + createTemplateAction, + parseRepoUrl, +} from '@backstage/plugin-scaffolder-node'; import { ScmIntegrationRegistry } from '@backstage/integration'; -import { parseRepoUrl } from '../publish/util'; import { getOctokitOptions } from './helpers'; import { Octokit } from 'octokit'; import Sodium from 'libsodium-wrappers'; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubIssuesLabel.examples.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubIssuesLabel.examples.test.ts similarity index 100% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubIssuesLabel.examples.test.ts rename to plugins/scaffolder-backend-module-github/src/actions/githubIssuesLabel.examples.test.ts diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubIssuesLabel.examples.ts b/plugins/scaffolder-backend-module-github/src/actions/githubIssuesLabel.examples.ts similarity index 100% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubIssuesLabel.examples.ts rename to plugins/scaffolder-backend-module-github/src/actions/githubIssuesLabel.examples.ts diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubIssuesLabel.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubIssuesLabel.test.ts similarity index 100% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubIssuesLabel.test.ts rename to plugins/scaffolder-backend-module-github/src/actions/githubIssuesLabel.test.ts diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubIssuesLabel.ts b/plugins/scaffolder-backend-module-github/src/actions/githubIssuesLabel.ts similarity index 96% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubIssuesLabel.ts rename to plugins/scaffolder-backend-module-github/src/actions/githubIssuesLabel.ts index 73a65ffb14..90f5a89dc7 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubIssuesLabel.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubIssuesLabel.ts @@ -18,11 +18,13 @@ import { GithubCredentialsProvider, ScmIntegrationRegistry, } from '@backstage/integration'; -import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; +import { + createTemplateAction, + parseRepoUrl, +} from '@backstage/plugin-scaffolder-node'; import { assertError, InputError } from '@backstage/errors'; import { Octokit } from 'octokit'; import { getOctokitOptions } from './helpers'; -import { parseRepoUrl } from '../publish/util'; import { examples } from './githubIssuesLabel.examples'; /** diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.examples.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubPullRequest.examples.test.ts similarity index 100% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.examples.test.ts rename to plugins/scaffolder-backend-module-github/src/actions/githubPullRequest.examples.test.ts diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.examples.ts b/plugins/scaffolder-backend-module-github/src/actions/githubPullRequest.examples.ts similarity index 100% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.examples.ts rename to plugins/scaffolder-backend-module-github/src/actions/githubPullRequest.examples.ts diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubPullRequest.test.ts similarity index 100% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.test.ts rename to plugins/scaffolder-backend-module-github/src/actions/githubPullRequest.test.ts diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.ts b/plugins/scaffolder-backend-module-github/src/actions/githubPullRequest.ts similarity index 98% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.ts rename to plugins/scaffolder-backend-module-github/src/actions/githubPullRequest.ts index 3b6e7c3ced..00e584226f 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubPullRequest.ts @@ -15,21 +15,21 @@ */ import path from 'path'; -import { parseRepoUrl } from './util'; import { GithubCredentialsProvider, ScmIntegrationRegistry, } from '@backstage/integration'; -import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; +import { + createTemplateAction, + parseRepoUrl, + SerializedFile, + serializeDirectoryContents, +} from '@backstage/plugin-scaffolder-node'; import { Octokit } from 'octokit'; import { InputError, CustomErrorBase } from '@backstage/errors'; import { resolveSafeChildPath } from '@backstage/backend-common'; import { createPullRequest } from 'octokit-plugin-create-pull-request'; -import { getOctokitOptions } from '../github/helpers'; -import { - SerializedFile, - serializeDirectoryContents, -} from '../../../../lib/files'; +import { getOctokitOptions } from './helpers'; import { Logger } from 'winston'; import { examples } from './githubPullRequest.examples'; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoCreate.examples.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubRepoCreate.examples.test.ts similarity index 96% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoCreate.examples.test.ts rename to plugins/scaffolder-backend-module-github/src/actions/githubRepoCreate.examples.test.ts index 71bbc7c1c6..2377e9a7eb 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoCreate.examples.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubRepoCreate.examples.test.ts @@ -16,7 +16,12 @@ import { TemplateAction } from '@backstage/plugin-scaffolder-node'; -jest.mock('../helpers'); +jest.mock('./gitHelpers', () => { + return { + ...jest.requireActual('./gitHelpers'), + entityRefToName: jest.fn(), + }; +}); import { getVoidLogger } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; @@ -27,7 +32,7 @@ import { } from '@backstage/integration'; import { PassThrough } from 'stream'; import { createGithubRepoCreateAction } from './githubRepoCreate'; -import { entityRefToName } from '../helpers'; +import { entityRefToName } from './gitHelpers'; import yaml from 'yaml'; import { examples } from './githubRepoCreate.examples'; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoCreate.examples.ts b/plugins/scaffolder-backend-module-github/src/actions/githubRepoCreate.examples.ts similarity index 100% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoCreate.examples.ts rename to plugins/scaffolder-backend-module-github/src/actions/githubRepoCreate.examples.ts diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoCreate.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubRepoCreate.test.ts similarity index 99% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoCreate.test.ts rename to plugins/scaffolder-backend-module-github/src/actions/githubRepoCreate.test.ts index b5b31d0773..4cb007275e 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoCreate.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubRepoCreate.test.ts @@ -16,7 +16,12 @@ import { TemplateAction } from '@backstage/plugin-scaffolder-node'; -jest.mock('../helpers'); +jest.mock('./gitHelpers', () => { + return { + ...jest.requireActual('./gitHelpers'), + entityRefToName: jest.fn(), + }; +}); import { getVoidLogger } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; @@ -28,7 +33,7 @@ import { import { when } from 'jest-when'; import { PassThrough } from 'stream'; import { createGithubRepoCreateAction } from './githubRepoCreate'; -import { entityRefToName } from '../helpers'; +import { entityRefToName } from './gitHelpers'; const publicKey = '2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvvcCU='; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoCreate.ts b/plugins/scaffolder-backend-module-github/src/actions/githubRepoCreate.ts similarity index 98% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoCreate.ts rename to plugins/scaffolder-backend-module-github/src/actions/githubRepoCreate.ts index e0fde3b193..735919794f 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoCreate.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubRepoCreate.ts @@ -20,8 +20,10 @@ import { ScmIntegrationRegistry, } from '@backstage/integration'; import { Octokit } from 'octokit'; -import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; -import { parseRepoUrl } from '../publish/util'; +import { + createTemplateAction, + parseRepoUrl, +} from '@backstage/plugin-scaffolder-node'; import { createGithubRepoWithCollaboratorsAndTopics, getOctokitOptions, diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoPush.examples.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubRepoPush.examples.test.ts similarity index 85% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoPush.examples.test.ts rename to plugins/scaffolder-backend-module-github/src/actions/githubRepoPush.examples.test.ts index 84d489272d..8f8c9bf8af 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoPush.examples.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubRepoPush.examples.test.ts @@ -13,7 +13,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { TemplateAction } from '@backstage/plugin-scaffolder-node'; +jest.mock('@backstage/plugin-scaffolder-node', () => { + return { + ...jest.requireActual('@backstage/plugin-scaffolder-node'), + initRepoAndPush: jest.fn().mockResolvedValue({ + commitHash: '220f19cc36b551763d157f1b5e4a4b446165dbd6', + }), + commitAndPushRepo: jest.fn().mockResolvedValue({ + commitHash: '220f19cc36b551763d157f1b5e4a4b446165dbd6', + }), + }; +}); + +import { + TemplateAction, + initRepoAndPush, +} from '@backstage/plugin-scaffolder-node'; import { getVoidLogger } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; import { @@ -22,7 +37,6 @@ import { ScmIntegrations, } from '@backstage/integration'; import { PassThrough } from 'stream'; -import { initRepoAndPush } from '../helpers'; import { createGithubRepoPushAction } from './githubRepoPush'; import { examples } from './githubRepoPush.examples'; import yaml from 'yaml'; @@ -48,7 +62,12 @@ jest.mock('@backstage/backend-common', () => ({ getVoidLogger: jest.requireActual('@backstage/backend-common').getVoidLogger, })); -jest.mock('../helpers'); +jest.mock('./helpers', () => { + return { + ...jest.requireActual('./helpers'), + entityRefToName: jest.fn(), + }; +}); const initRepoAndPushMocked = initRepoAndPush as jest.Mock< Promise<{ commitHash: string }> @@ -98,6 +117,7 @@ describe('github:repo:push examples', () => { githubCredentialsProvider = DefaultGithubCredentialsProvider.fromIntegrations(integrations); + action = createGithubRepoPushAction({ integrations, config, diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoPush.examples.ts b/plugins/scaffolder-backend-module-github/src/actions/githubRepoPush.examples.ts similarity index 100% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoPush.examples.ts rename to plugins/scaffolder-backend-module-github/src/actions/githubRepoPush.examples.ts diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoPush.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubRepoPush.test.ts similarity index 96% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoPush.test.ts rename to plugins/scaffolder-backend-module-github/src/actions/githubRepoPush.test.ts index 8630dfab56..e16da0981d 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoPush.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubRepoPush.test.ts @@ -35,9 +35,30 @@ jest.mock('@backstage/backend-common', () => ({ getVoidLogger: jest.requireActual('@backstage/backend-common').getVoidLogger, })); -jest.mock('../helpers'); +jest.mock('./gitHelpers', () => { + return { + ...jest.requireActual('./gitHelpers'), + entityRefToName: jest.fn(), + enableBranchProtectionOnDefaultRepoBranch: jest.fn(), + }; +}); -import { TemplateAction } from '@backstage/plugin-scaffolder-node'; +jest.mock('@backstage/plugin-scaffolder-node', () => { + return { + ...jest.requireActual('@backstage/plugin-scaffolder-node'), + initRepoAndPush: jest.fn().mockResolvedValue({ + commitHash: '220f19cc36b551763d157f1b5e4a4b446165dbd6', + }), + commitAndPushRepo: jest.fn().mockResolvedValue({ + commitHash: '220f19cc36b551763d157f1b5e4a4b446165dbd6', + }), + }; +}); + +import { + TemplateAction, + initRepoAndPush, +} from '@backstage/plugin-scaffolder-node'; import { getVoidLogger } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; import { @@ -46,10 +67,7 @@ import { ScmIntegrations, } from '@backstage/integration'; import { PassThrough } from 'stream'; -import { - enableBranchProtectionOnDefaultRepoBranch, - initRepoAndPush, -} from '../helpers'; +import { enableBranchProtectionOnDefaultRepoBranch } from './gitHelpers'; import { createGithubRepoPushAction } from './githubRepoPush'; const initRepoAndPushMocked = initRepoAndPush as jest.Mock< diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoPush.ts b/plugins/scaffolder-backend-module-github/src/actions/githubRepoPush.ts similarity index 98% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoPush.ts rename to plugins/scaffolder-backend-module-github/src/actions/githubRepoPush.ts index e30eedad02..5b9db78f48 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoPush.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubRepoPush.ts @@ -21,8 +21,10 @@ import { ScmIntegrationRegistry, } from '@backstage/integration'; import { Octokit } from 'octokit'; -import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; -import { parseRepoUrl } from '../publish/util'; +import { + createTemplateAction, + parseRepoUrl, +} from '@backstage/plugin-scaffolder-node'; import { getOctokitOptions, initRepoPushAndProtect } from './helpers'; import * as inputProps from './inputProperties'; import * as outputProps from './outputProperties'; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubWebhook.examples.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubWebhook.examples.test.ts similarity index 100% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubWebhook.examples.test.ts rename to plugins/scaffolder-backend-module-github/src/actions/githubWebhook.examples.test.ts diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubWebhook.examples.ts b/plugins/scaffolder-backend-module-github/src/actions/githubWebhook.examples.ts similarity index 100% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubWebhook.examples.ts rename to plugins/scaffolder-backend-module-github/src/actions/githubWebhook.examples.ts diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubWebhook.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubWebhook.test.ts similarity index 100% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubWebhook.test.ts rename to plugins/scaffolder-backend-module-github/src/actions/githubWebhook.test.ts diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubWebhook.ts b/plugins/scaffolder-backend-module-github/src/actions/githubWebhook.ts similarity index 97% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubWebhook.ts rename to plugins/scaffolder-backend-module-github/src/actions/githubWebhook.ts index 5589c951a5..984029076e 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubWebhook.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubWebhook.ts @@ -18,12 +18,14 @@ import { GithubCredentialsProvider, ScmIntegrationRegistry, } from '@backstage/integration'; -import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; +import { + createTemplateAction, + parseRepoUrl, +} from '@backstage/plugin-scaffolder-node'; import { emitterEventNames } from '@octokit/webhooks'; import { assertError, InputError } from '@backstage/errors'; import { Octokit } from 'octokit'; import { getOctokitOptions } from './helpers'; -import { parseRepoUrl } from '../publish/util'; import { examples } from './githubWebhook.examples'; /** diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/helpers.ts b/plugins/scaffolder-backend-module-github/src/actions/helpers.ts similarity index 97% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/helpers.ts rename to plugins/scaffolder-backend-module-github/src/actions/helpers.ts index d91f3bf3a2..c6c4bd4ce5 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/helpers.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/helpers.ts @@ -24,13 +24,18 @@ import { import { OctokitOptions } from '@octokit/core/dist-types/types'; import { Octokit } from 'octokit'; import { Logger } from 'winston'; + +import { + getRepoSourceDirectory, + initRepoAndPush, + parseRepoUrl, +} from '@backstage/plugin-scaffolder-node'; + +import Sodium from 'libsodium-wrappers'; import { enableBranchProtectionOnDefaultRepoBranch, - initRepoAndPush, -} from '../helpers'; -import { getRepoSourceDirectory, parseRepoUrl } from '../publish/util'; -import { entityRefToName } from '../../builtin/helpers'; -import Sodium from 'libsodium-wrappers'; + entityRefToName, +} from './gitHelpers'; const DEFAULT_TIMEOUT_MS = 60_000; @@ -422,3 +427,12 @@ async function validateAccessTeam(client: Octokit, access: string) { } } } + +export function getGitCommitMessage( + gitCommitMessage: string | undefined, + config: Config, +): string | undefined { + return gitCommitMessage + ? gitCommitMessage + : config.getOptionalString('scaffolder.defaultCommitMessage'); +} diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/index.ts b/plugins/scaffolder-backend-module-github/src/actions/index.ts similarity index 89% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/index.ts rename to plugins/scaffolder-backend-module-github/src/actions/index.ts index ecc8ce59f2..9c3927f31d 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/index.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/index.ts @@ -21,3 +21,6 @@ export { createGithubRepoPushAction } from './githubRepoPush'; export { createGithubWebhookAction } from './githubWebhook'; export { createGithubDeployKeyAction } from './githubDeployKey'; export { createGithubEnvironmentAction } from './githubEnvironment'; + +export { createPublishGithubPullRequestAction } from './githubPullRequest'; +export { createPublishGithubAction } from './github'; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/inputProperties.ts b/plugins/scaffolder-backend-module-github/src/actions/inputProperties.ts similarity index 100% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/inputProperties.ts rename to plugins/scaffolder-backend-module-github/src/actions/inputProperties.ts diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/outputProperties.ts b/plugins/scaffolder-backend-module-github/src/actions/outputProperties.ts similarity index 100% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/outputProperties.ts rename to plugins/scaffolder-backend-module-github/src/actions/outputProperties.ts diff --git a/plugins/scaffolder-backend-module-github/src/index.ts b/plugins/scaffolder-backend-module-github/src/index.ts new file mode 100644 index 0000000000..b4d8dbcb6d --- /dev/null +++ b/plugins/scaffolder-backend-module-github/src/index.ts @@ -0,0 +1,23 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * The github module for @backstage/plugin-scaffolder-backend. + * + * @packageDocumentation + */ + +export * from './actions'; From f212ff40a97f166caf904bf93f18c125e859fcd1 Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 6 Dec 2023 12:32:28 +0100 Subject: [PATCH 085/275] chore: create azure module Signed-off-by: blam --- .../.eslintrc.js | 1 + .../scaffolder-backend-module-azure/README.md | 5 +++ .../package.json | 40 +++++++++++++++++++ .../src/actions}/azure.examples.test.ts | 5 ++- .../src/actions}/azure.examples.ts | 0 .../src/actions}/azure.test.ts | 5 ++- .../src/actions}/azure.ts | 9 +++-- .../src/actions/index.ts | 16 ++++++++ .../src/index.ts | 23 +++++++++++ 9 files changed, 97 insertions(+), 7 deletions(-) create mode 100644 plugins/scaffolder-backend-module-azure/.eslintrc.js create mode 100644 plugins/scaffolder-backend-module-azure/README.md create mode 100644 plugins/scaffolder-backend-module-azure/package.json rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/publish => scaffolder-backend-module-azure/src/actions}/azure.examples.test.ts (95%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/publish => scaffolder-backend-module-azure/src/actions}/azure.examples.ts (100%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/publish => scaffolder-backend-module-azure/src/actions}/azure.test.ts (98%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/publish => scaffolder-backend-module-azure/src/actions}/azure.ts (97%) create mode 100644 plugins/scaffolder-backend-module-azure/src/actions/index.ts create mode 100644 plugins/scaffolder-backend-module-azure/src/index.ts diff --git a/plugins/scaffolder-backend-module-azure/.eslintrc.js b/plugins/scaffolder-backend-module-azure/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/scaffolder-backend-module-azure/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/scaffolder-backend-module-azure/README.md b/plugins/scaffolder-backend-module-azure/README.md new file mode 100644 index 0000000000..505ef36db1 --- /dev/null +++ b/plugins/scaffolder-backend-module-azure/README.md @@ -0,0 +1,5 @@ +# @backstage/plugin-scaffolder-backend-module-azure + +The azure module for [@backstage/plugin-scaffolder-backend](https://www.npmjs.com/package/@backstage/plugin-scaffolder-backend). + +_This plugin was created through the Backstage CLI_ diff --git a/plugins/scaffolder-backend-module-azure/package.json b/plugins/scaffolder-backend-module-azure/package.json new file mode 100644 index 0000000000..4bc4209dee --- /dev/null +++ b/plugins/scaffolder-backend-module-azure/package.json @@ -0,0 +1,40 @@ +{ + "name": "@backstage/plugin-scaffolder-backend-module-azure", + "description": "The azure module for @backstage/plugin-scaffolder-backend", + "version": "0.0.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "backend-plugin-module" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/backend-common": "workspace:^", + "@backstage/config": "workspace:^", + "@backstage/errors": "workspace:^", + "@backstage/integration": "workspace:^", + "@backstage/plugin-scaffolder-node": "workspace:^", + "azure-devops-node-api": "^11.0.1", + "yaml": "^2.0.0" + }, + "devDependencies": { + "@backstage/cli": "workspace:^" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/azure.examples.test.ts b/plugins/scaffolder-backend-module-azure/src/actions/azure.examples.test.ts similarity index 95% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/azure.examples.test.ts rename to plugins/scaffolder-backend-module-azure/src/actions/azure.examples.test.ts index e4fd18ef59..27989650ce 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/azure.examples.test.ts +++ b/plugins/scaffolder-backend-module-azure/src/actions/azure.examples.test.ts @@ -21,7 +21,7 @@ import { ScmIntegrations } from '@backstage/integration'; import { getVoidLogger } from '@backstage/backend-common'; import { WebApi } from 'azure-devops-node-api'; import { PassThrough } from 'stream'; -import { initRepoAndPush } from '../helpers'; +import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; import { examples } from './azure.examples'; jest.mock('azure-devops-node-api', () => ({ @@ -29,8 +29,9 @@ jest.mock('azure-devops-node-api', () => ({ getPersonalAccessTokenHandler: jest.fn().mockReturnValue(() => {}), })); -jest.mock('../helpers', () => { +jest.mock('@backstage/plugin-scaffolder-node', () => { return { + ...jest.requireActual('@backstage/plugin-scaffolder-node'), initRepoAndPush: jest.fn().mockResolvedValue({ commitHash: '220f19cc36b551763d157f1b5e4a4b446165dbd6', }), diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/azure.examples.ts b/plugins/scaffolder-backend-module-azure/src/actions/azure.examples.ts similarity index 100% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/azure.examples.ts rename to plugins/scaffolder-backend-module-azure/src/actions/azure.examples.ts diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/azure.test.ts b/plugins/scaffolder-backend-module-azure/src/actions/azure.test.ts similarity index 98% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/azure.test.ts rename to plugins/scaffolder-backend-module-azure/src/actions/azure.test.ts index 9b7673ea29..4401e01007 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/azure.test.ts +++ b/plugins/scaffolder-backend-module-azure/src/actions/azure.test.ts @@ -19,8 +19,9 @@ jest.mock('azure-devops-node-api', () => ({ getPersonalAccessTokenHandler: jest.fn().mockReturnValue(() => {}), })); -jest.mock('../helpers', () => { +jest.mock('@backstage/plugin-scaffolder-node', () => { return { + ...jest.requireActual('@backstage/plugin-scaffolder-node'), initRepoAndPush: jest.fn().mockResolvedValue({ commitHash: '220f19cc36b551763d157f1b5e4a4b446165dbd6', }), @@ -36,7 +37,7 @@ import { ConfigReader } from '@backstage/config'; import { getVoidLogger } from '@backstage/backend-common'; import { WebApi } from 'azure-devops-node-api'; import { PassThrough } from 'stream'; -import { initRepoAndPush } from '../helpers'; +import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; describe('publish:azure', () => { const config = new ConfigReader({ diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/azure.ts b/plugins/scaffolder-backend-module-azure/src/actions/azure.ts similarity index 97% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/azure.ts rename to plugins/scaffolder-backend-module-azure/src/actions/azure.ts index a7df154687..e90cfeade4 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/azure.ts +++ b/plugins/scaffolder-backend-module-azure/src/actions/azure.ts @@ -19,15 +19,18 @@ import { DefaultAzureDevOpsCredentialsProvider, ScmIntegrationRegistry, } from '@backstage/integration'; -import { initRepoAndPush } from '../helpers'; +import { + initRepoAndPush, + getRepoSourceDirectory, + parseRepoUrl, + createTemplateAction, +} from '@backstage/plugin-scaffolder-node'; import { GitRepositoryCreateOptions } from 'azure-devops-node-api/interfaces/GitInterfaces'; import { getBearerHandler, getPersonalAccessTokenHandler, WebApi, } from 'azure-devops-node-api'; -import { getRepoSourceDirectory, parseRepoUrl } from './util'; -import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; import { Config } from '@backstage/config'; import { examples } from './azure.examples'; diff --git a/plugins/scaffolder-backend-module-azure/src/actions/index.ts b/plugins/scaffolder-backend-module-azure/src/actions/index.ts new file mode 100644 index 0000000000..76ea7c2f07 --- /dev/null +++ b/plugins/scaffolder-backend-module-azure/src/actions/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export * from './azure'; diff --git a/plugins/scaffolder-backend-module-azure/src/index.ts b/plugins/scaffolder-backend-module-azure/src/index.ts new file mode 100644 index 0000000000..d64ca54077 --- /dev/null +++ b/plugins/scaffolder-backend-module-azure/src/index.ts @@ -0,0 +1,23 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * The azure module for @backstage/plugin-scaffolder-backend. + * + * @packageDocumentation + */ + +export * from './actions'; From fbb1071987616a783baf117a91d7d8317ffb46f5 Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 6 Dec 2023 12:33:02 +0100 Subject: [PATCH 086/275] chore: create bitbucket modules Signed-off-by: blam --- .../.eslintrc.js | 1 + .../README.md | 5 +++ .../package.json | 42 +++++++++++++++++++ .../src/actions}/bitbucket.examples.test.ts | 5 ++- .../src/actions}/bitbucket.examples.ts | 0 .../src/actions}/bitbucket.test.ts | 6 +-- .../src/actions}/bitbucket.ts | 9 ++-- .../src/actions}/bitbucketCloud.test.ts | 5 ++- .../src/actions}/bitbucketCloud.ts | 10 +++-- .../src/actions}/bitbucketServer.test.ts | 5 ++- .../src/actions}/bitbucketServer.ts | 10 +++-- .../bitbucketServerPullRequest.test.ts | 3 +- .../actions}/bitbucketServerPullRequest.ts | 6 ++- .../src/actions/index.ts | 19 +++++++++ .../src/index.ts | 23 ++++++++++ 15 files changed, 128 insertions(+), 21 deletions(-) create mode 100644 plugins/scaffolder-backend-module-bitbucket/.eslintrc.js create mode 100644 plugins/scaffolder-backend-module-bitbucket/README.md create mode 100644 plugins/scaffolder-backend-module-bitbucket/package.json rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/publish => scaffolder-backend-module-bitbucket/src/actions}/bitbucket.examples.test.ts (98%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/publish => scaffolder-backend-module-bitbucket/src/actions}/bitbucket.examples.ts (100%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/publish => scaffolder-backend-module-bitbucket/src/actions}/bitbucket.test.ts (98%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/publish => scaffolder-backend-module-bitbucket/src/actions}/bitbucket.ts (98%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/publish => scaffolder-backend-module-bitbucket/src/actions}/bitbucketCloud.test.ts (98%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/publish => scaffolder-backend-module-bitbucket/src/actions}/bitbucketCloud.ts (97%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/publish => scaffolder-backend-module-bitbucket/src/actions}/bitbucketServer.test.ts (99%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/publish => scaffolder-backend-module-bitbucket/src/actions}/bitbucketServer.ts (97%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/publish => scaffolder-backend-module-bitbucket/src/actions}/bitbucketServerPullRequest.test.ts (98%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/publish => scaffolder-backend-module-bitbucket/src/actions}/bitbucketServerPullRequest.ts (98%) create mode 100644 plugins/scaffolder-backend-module-bitbucket/src/actions/index.ts create mode 100644 plugins/scaffolder-backend-module-bitbucket/src/index.ts diff --git a/plugins/scaffolder-backend-module-bitbucket/.eslintrc.js b/plugins/scaffolder-backend-module-bitbucket/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/scaffolder-backend-module-bitbucket/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/scaffolder-backend-module-bitbucket/README.md b/plugins/scaffolder-backend-module-bitbucket/README.md new file mode 100644 index 0000000000..90b8680e80 --- /dev/null +++ b/plugins/scaffolder-backend-module-bitbucket/README.md @@ -0,0 +1,5 @@ +# @backstage/plugin-scaffolder-backend-module-bitbucket + +The bitbucket module for [@backstage/plugin-scaffolder-backend](https://www.npmjs.com/package/@backstage/plugin-scaffolder-backend). + +_This plugin was created through the Backstage CLI_ diff --git a/plugins/scaffolder-backend-module-bitbucket/package.json b/plugins/scaffolder-backend-module-bitbucket/package.json new file mode 100644 index 0000000000..4c92ce01a2 --- /dev/null +++ b/plugins/scaffolder-backend-module-bitbucket/package.json @@ -0,0 +1,42 @@ +{ + "name": "@backstage/plugin-scaffolder-backend-module-bitbucket", + "description": "The bitbucket module for @backstage/plugin-scaffolder-backend", + "version": "0.0.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "backend-plugin-module" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/backend-common": "workspace:^", + "@backstage/config": "workspace:^", + "@backstage/errors": "workspace:^", + "@backstage/integration": "workspace:^", + "@backstage/plugin-scaffolder-node": "workspace:^", + "node-fetch": "^2.6.7", + "yaml": "^2.0.0" + }, + "devDependencies": { + "@backstage/backend-test-utils": "workspace:^", + "@backstage/cli": "workspace:^", + "msw": "^1.0.0" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucket.examples.test.ts b/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.examples.test.ts similarity index 98% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucket.examples.test.ts rename to plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.examples.test.ts index a1564d0498..73325ab5bf 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucket.examples.test.ts +++ b/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.examples.test.ts @@ -14,8 +14,9 @@ * limitations under the License. */ -jest.mock('../helpers', () => { +jest.mock('@backstage/plugin-scaffolder-node', () => { return { + ...jest.requireActual('@backstage/plugin-scaffolder-node'), initRepoAndPush: jest.fn().mockResolvedValue({ commitHash: '220f19cc36b551763d157f1b5e4a4b446165dbd6', }), @@ -33,7 +34,7 @@ import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; import { getVoidLogger } from '@backstage/backend-common'; import { PassThrough } from 'stream'; -import { initRepoAndPush } from '../helpers'; +import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; import yaml from 'yaml'; import { sep } from 'path'; import { examples } from './bitbucket.examples'; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucket.examples.ts b/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.examples.ts similarity index 100% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucket.examples.ts rename to plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.examples.ts diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucket.test.ts b/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.test.ts similarity index 98% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucket.test.ts rename to plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.test.ts index 5d46a28a60..d6e068c039 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucket.test.ts +++ b/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.test.ts @@ -14,8 +14,9 @@ * limitations under the License. */ -jest.mock('../helpers', () => { +jest.mock('@backstage/plugin-scaffolder-node', () => { return { + ...jest.requireActual('@backstage/plugin-scaffolder-node'), initRepoAndPush: jest.fn().mockResolvedValue({ commitHash: '220f19cc36b551763d157f1b5e4a4b446165dbd6', }), @@ -24,7 +25,6 @@ jest.mock('../helpers', () => { }), }; }); - import { createPublishBitbucketAction } from './bitbucket'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; @@ -33,7 +33,7 @@ import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; import { getVoidLogger } from '@backstage/backend-common'; import { PassThrough } from 'stream'; -import { initRepoAndPush } from '../helpers'; +import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; describe('publish:bitbucket', () => { const config = new ConfigReader({ diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucket.ts b/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.ts similarity index 98% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucket.ts rename to plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.ts index a4d664e0e7..76fe1de5df 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucket.ts +++ b/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.ts @@ -19,10 +19,13 @@ import { BitbucketIntegrationConfig, ScmIntegrationRegistry, } from '@backstage/integration'; -import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; +import { + createTemplateAction, + initRepoAndPush, + getRepoSourceDirectory, + parseRepoUrl, +} from '@backstage/plugin-scaffolder-node'; import fetch, { Response, RequestInit } from 'node-fetch'; -import { initRepoAndPush } from '../helpers'; -import { getRepoSourceDirectory, parseRepoUrl } from './util'; import { Config } from '@backstage/config'; import { examples } from './bitbucket.examples'; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucketCloud.test.ts b/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucketCloud.test.ts similarity index 98% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucketCloud.test.ts rename to plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucketCloud.test.ts index 3159bfc562..7045d58e01 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucketCloud.test.ts +++ b/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucketCloud.test.ts @@ -14,8 +14,9 @@ * limitations under the License. */ -jest.mock('../helpers', () => { +jest.mock('@backstage/plugin-scaffolder-node', () => { return { + ...jest.requireActual('@backstage/plugin-scaffolder-node'), initRepoAndPush: jest.fn().mockResolvedValue({ commitHash: '220f19cc36b551763d157f1b5e4a4b446165dbd6', }), @@ -33,7 +34,7 @@ import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; import { getVoidLogger } from '@backstage/backend-common'; import { PassThrough } from 'stream'; -import { initRepoAndPush } from '../helpers'; +import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; describe('publish:bitbucketCloud', () => { const config = new ConfigReader({ diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucketCloud.ts b/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucketCloud.ts similarity index 97% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucketCloud.ts rename to plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucketCloud.ts index 00529d5856..c69ae0b147 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucketCloud.ts +++ b/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucketCloud.ts @@ -16,10 +16,14 @@ import { InputError } from '@backstage/errors'; import { ScmIntegrationRegistry } from '@backstage/integration'; -import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; +import { + createTemplateAction, + initRepoAndPush, + getRepoSourceDirectory, + parseRepoUrl, +} from '@backstage/plugin-scaffolder-node'; import fetch, { Response, RequestInit } from 'node-fetch'; -import { initRepoAndPush } from '../helpers'; -import { getRepoSourceDirectory, parseRepoUrl } from './util'; + import { Config } from '@backstage/config'; const createRepository = async (opts: { diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucketServer.test.ts b/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucketServer.test.ts similarity index 99% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucketServer.test.ts rename to plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucketServer.test.ts index 67a29210fc..ab7b52996f 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucketServer.test.ts +++ b/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucketServer.test.ts @@ -14,8 +14,9 @@ * limitations under the License. */ -jest.mock('../helpers', () => { +jest.mock('@backstage/plugin-scaffolder-node', () => { return { + ...jest.requireActual('@backstage/plugin-scaffolder-node'), initRepoAndPush: jest.fn().mockResolvedValue({ commitHash: '220f19cc36b551763d157f1b5e4a4b446165dbd6', }), @@ -33,7 +34,7 @@ import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; import { getVoidLogger } from '@backstage/backend-common'; import { PassThrough } from 'stream'; -import { initRepoAndPush } from '../helpers'; +import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; describe('publish:bitbucketServer', () => { const config = new ConfigReader({ diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucketServer.ts b/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucketServer.ts similarity index 97% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucketServer.ts rename to plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucketServer.ts index 66b7a46f77..31125deab2 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucketServer.ts +++ b/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucketServer.ts @@ -19,10 +19,14 @@ import { getBitbucketServerRequestOptions, ScmIntegrationRegistry, } from '@backstage/integration'; -import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; +import { + createTemplateAction, + initRepoAndPush, + getRepoSourceDirectory, + parseRepoUrl, +} from '@backstage/plugin-scaffolder-node'; import fetch, { Response, RequestInit } from 'node-fetch'; -import { initRepoAndPush } from '../helpers'; -import { getRepoSourceDirectory, parseRepoUrl } from './util'; + import { Config } from '@backstage/config'; const createRepository = async (opts: { diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucketServerPullRequest.test.ts b/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucketServerPullRequest.test.ts similarity index 98% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucketServerPullRequest.test.ts rename to plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucketServerPullRequest.test.ts index af3999097f..3af47853c3 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucketServerPullRequest.test.ts +++ b/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucketServerPullRequest.test.ts @@ -14,8 +14,9 @@ * limitations under the License. */ -jest.mock('../helpers', () => { +jest.mock('@backstage/plugin-scaffolder-node', () => { return { + ...jest.requireActual('@backstage/plugin-scaffolder-node'), initRepoAndPush: jest.fn().mockResolvedValue({ commitHash: '220f19cc36b551763d157f1b5e4a4b446165dbd6', }), diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucketServerPullRequest.ts b/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucketServerPullRequest.ts similarity index 98% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucketServerPullRequest.ts rename to plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucketServerPullRequest.ts index 79711b9d69..dc75145ebc 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucketServerPullRequest.ts +++ b/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucketServerPullRequest.ts @@ -19,9 +19,11 @@ import { getBitbucketServerRequestOptions, ScmIntegrationRegistry, } from '@backstage/integration'; -import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; +import { + createTemplateAction, + parseRepoUrl, +} from '@backstage/plugin-scaffolder-node'; import fetch, { RequestInit, Response } from 'node-fetch'; -import { parseRepoUrl } from './util'; import { Config } from '@backstage/config'; const createPullRequest = async (opts: { diff --git a/plugins/scaffolder-backend-module-bitbucket/src/actions/index.ts b/plugins/scaffolder-backend-module-bitbucket/src/actions/index.ts new file mode 100644 index 0000000000..1093b07785 --- /dev/null +++ b/plugins/scaffolder-backend-module-bitbucket/src/actions/index.ts @@ -0,0 +1,19 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export * from './bitbucket'; +export * from './bitbucketCloud'; +export * from './bitbucketServer'; +export * from './bitbucketServerPullRequest'; diff --git a/plugins/scaffolder-backend-module-bitbucket/src/index.ts b/plugins/scaffolder-backend-module-bitbucket/src/index.ts new file mode 100644 index 0000000000..6448b82c8b --- /dev/null +++ b/plugins/scaffolder-backend-module-bitbucket/src/index.ts @@ -0,0 +1,23 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * The bitbucket module for @backstage/plugin-scaffolder-backend. + * + * @packageDocumentation + */ + +export * from './actions'; From 88c9a158c2adbb2374d29835359bda05dfd0b6ce Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 6 Dec 2023 12:45:30 +0100 Subject: [PATCH 087/275] chore: added gitlab module Signed-off-by: blam --- .../package.json | 6 ++++-- .../src/actions}/gitlab.examples.test.ts | 5 +++-- .../src/actions}/gitlab.examples.ts | 0 .../src/actions}/gitlab.test.ts | 5 +++-- .../src/actions}/gitlab.ts | 7 +++++-- .../src/actions}/gitlabMergeRequest.test.ts | 0 .../src/actions}/gitlabMergeRequest.ts | 8 ++++--- .../src/actions/index.ts | 21 +++++++++++++++++++ .../src/index.ts | 5 +---- 9 files changed, 42 insertions(+), 15 deletions(-) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/publish => scaffolder-backend-module-gitlab/src/actions}/gitlab.examples.test.ts (94%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/publish => scaffolder-backend-module-gitlab/src/actions}/gitlab.examples.ts (100%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/publish => scaffolder-backend-module-gitlab/src/actions}/gitlab.test.ts (98%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/publish => scaffolder-backend-module-gitlab/src/actions}/gitlab.ts (99%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/publish => scaffolder-backend-module-gitlab/src/actions}/gitlabMergeRequest.test.ts (100%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/publish => scaffolder-backend-module-gitlab/src/actions}/gitlabMergeRequest.ts (97%) create mode 100644 plugins/scaffolder-backend-module-gitlab/src/actions/index.ts diff --git a/plugins/scaffolder-backend-module-gitlab/package.json b/plugins/scaffolder-backend-module-gitlab/package.json index 94641be81c..d67aefbd27 100644 --- a/plugins/scaffolder-backend-module-gitlab/package.json +++ b/plugins/scaffolder-backend-module-gitlab/package.json @@ -31,16 +31,18 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { + "@backstage/backend-common": "workspace:^", "@backstage/config": "workspace:^", "@backstage/errors": "workspace:^", "@backstage/integration": "workspace:^", "@backstage/plugin-scaffolder-node": "workspace:^", - "@gitbeaker/node": "^35.8.0", + "@gitbeaker/core": "^35.8.0", + "@gitbeaker/node": "^35.1.0", "yaml": "^2.0.0", "zod": "^3.21.4" }, "devDependencies": { - "@backstage/backend-common": "workspace:^", + "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^" }, diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlab.examples.test.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlab.examples.test.ts similarity index 94% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlab.examples.test.ts rename to plugins/scaffolder-backend-module-gitlab/src/actions/gitlab.examples.test.ts index 5d58431c61..e5aa610ebc 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlab.examples.test.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlab.examples.test.ts @@ -15,8 +15,9 @@ */ import yaml from 'yaml'; -jest.mock('../helpers', () => { +jest.mock('@backstage/plugin-scaffolder-node', () => { return { + ...jest.requireActual('@backstage/plugin-scaffolder-node'), initRepoAndPush: jest.fn().mockResolvedValue({ commitHash: '220f19cc36b551763d157f1b5e4a4b446165dbd6', }), @@ -27,11 +28,11 @@ jest.mock('../helpers', () => { }); import { createPublishGitlabAction } from './gitlab'; +import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; import { getVoidLogger } from '@backstage/backend-common'; import { PassThrough } from 'stream'; -import { initRepoAndPush } from '../helpers'; import { examples } from './gitlab.examples'; const mockGitlabClient = { diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlab.examples.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlab.examples.ts similarity index 100% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlab.examples.ts rename to plugins/scaffolder-backend-module-gitlab/src/actions/gitlab.examples.ts diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlab.test.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlab.test.ts similarity index 98% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlab.test.ts rename to plugins/scaffolder-backend-module-gitlab/src/actions/gitlab.test.ts index b2f3dc6480..5aca0a73e5 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlab.test.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlab.test.ts @@ -14,8 +14,9 @@ * limitations under the License. */ -jest.mock('../helpers', () => { +jest.mock('@backstage/plugin-scaffolder-node', () => { return { + ...jest.requireActual('@backstage/plugin-scaffolder-node'), initRepoAndPush: jest.fn().mockResolvedValue({ commitHash: '220f19cc36b551763d157f1b5e4a4b446165dbd6', }), @@ -30,7 +31,7 @@ import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; import { getVoidLogger } from '@backstage/backend-common'; import { PassThrough } from 'stream'; -import { initRepoAndPush } from '../helpers'; +import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; const mockGitlabClient = { Namespaces: { diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlab.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlab.ts similarity index 99% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlab.ts rename to plugins/scaffolder-backend-module-gitlab/src/actions/gitlab.ts index 6d86841a20..22f875ca8d 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlab.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlab.ts @@ -18,8 +18,11 @@ import { InputError } from '@backstage/errors'; import { ScmIntegrationRegistry } from '@backstage/integration'; import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; import { Gitlab } from '@gitbeaker/node'; -import { initRepoAndPush } from '../helpers'; -import { getRepoSourceDirectory, parseRepoUrl } from './util'; +import { + initRepoAndPush, + getRepoSourceDirectory, + parseRepoUrl, +} from '@backstage/plugin-scaffolder-node'; import { Config } from '@backstage/config'; import { examples } from './gitlab.examples'; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlabMergeRequest.test.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.test.ts similarity index 100% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlabMergeRequest.test.ts rename to plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.test.ts diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlabMergeRequest.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.ts similarity index 97% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlabMergeRequest.ts rename to plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.ts index 8abb53288c..f6c4734729 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlabMergeRequest.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.ts @@ -14,15 +14,17 @@ * limitations under the License. */ -import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; +import { + createTemplateAction, + parseRepoUrl, + serializeDirectoryContents, +} from '@backstage/plugin-scaffolder-node'; import { Gitlab } from '@gitbeaker/node'; import { Types } from '@gitbeaker/core'; import path from 'path'; import { ScmIntegrationRegistry } from '@backstage/integration'; import { InputError } from '@backstage/errors'; -import { parseRepoUrl } from './util'; import { resolveSafeChildPath } from '@backstage/backend-common'; -import { serializeDirectoryContents } from '../../../../lib/files'; /** * Create a new action that creates a gitlab merge request. diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/index.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/index.ts new file mode 100644 index 0000000000..e915293860 --- /dev/null +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/index.ts @@ -0,0 +1,21 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export * from './createGitlabGroupEnsureExistsAction'; +export * from './createGitlabProjectDeployTokenAction'; +export * from './createGitlabProjectAccessTokenAction'; +export * from './createGitlabProjectVariableAction'; +export * from './gitlab'; +export * from './gitlabMergeRequest'; diff --git a/plugins/scaffolder-backend-module-gitlab/src/index.ts b/plugins/scaffolder-backend-module-gitlab/src/index.ts index 4fd4dee35b..844f753344 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/index.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/index.ts @@ -19,7 +19,4 @@ * * @packageDocumentation */ -export * from './actions/createGitlabGroupEnsureExistsAction'; -export * from './actions/createGitlabProjectDeployTokenAction'; -export * from './actions/createGitlabProjectAccessTokenAction'; -export * from './actions/createGitlabProjectVariableAction'; +export * from './actions'; From 81f57ff279193aca741dfcb0c8822f7401e64218 Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 6 Dec 2023 12:45:46 +0100 Subject: [PATCH 088/275] chore: move some other things around a little bit Signed-off-by: blam --- plugins/scaffolder-backend/package.json | 11 +- .../actions/builtin/publish/util.ts | 119 +--------------- plugins/scaffolder-node/src/actions/index.ts | 2 + .../src/actions/repoHelpers.ts | 127 ++++++++++++++++++ plugins/scaffolder-node/src/actions/util.ts | 112 +++++++++++++++ .../deserializeDirectoryContents.test.ts | 0 .../files/deserializeDirectoryContents.ts | 0 .../src}/files/index.ts | 0 .../files/serializeDirectoryContents.test.ts | 0 .../src}/files/serializeDirectoryContents.ts | 0 .../src}/files/types.ts | 0 plugins/scaffolder-node/src/index.ts | 1 + .../scaffolder-react/src/components/types.ts | 1 + 13 files changed, 249 insertions(+), 124 deletions(-) create mode 100644 plugins/scaffolder-node/src/actions/repoHelpers.ts create mode 100644 plugins/scaffolder-node/src/actions/util.ts rename plugins/{scaffolder-backend/src/lib => scaffolder-node/src}/files/deserializeDirectoryContents.test.ts (100%) rename plugins/{scaffolder-backend/src/lib => scaffolder-node/src}/files/deserializeDirectoryContents.ts (100%) rename plugins/{scaffolder-backend/src/lib => scaffolder-node/src}/files/index.ts (100%) rename plugins/{scaffolder-backend/src/lib => scaffolder-node/src}/files/serializeDirectoryContents.test.ts (100%) rename plugins/{scaffolder-backend/src/lib => scaffolder-node/src}/files/serializeDirectoryContents.ts (100%) rename plugins/{scaffolder-backend/src/lib => scaffolder-node/src}/files/types.ts (100%) diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index f1ea2a3517..d89fc2f3ca 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -64,9 +64,6 @@ "@backstage/plugin-scaffolder-common": "workspace:^", "@backstage/plugin-scaffolder-node": "workspace:^", "@backstage/types": "workspace:^", - "@gitbeaker/core": "^35.6.0", - "@gitbeaker/node": "^35.1.0", - "@octokit/webhooks": "^10.0.0", "@types/express": "^4.17.6", "@types/luxon": "^3.0.0", "azure-devops-node-api": "^11.0.1", @@ -83,14 +80,11 @@ "isomorphic-git": "^1.23.0", "jsonschema": "^1.2.6", "knex": "^3.0.0", - "libsodium-wrappers": "^0.7.11", "lodash": "^4.17.21", "luxon": "^3.0.0", "morgan": "^1.10.0", "node-fetch": "^2.6.7", "nunjucks": "^3.2.3", - "octokit": "^2.0.0", - "octokit-plugin-create-pull-request": "^3.10.0", "p-limit": "^3.1.0", "p-queue": "^6.6.2", "prom-client": "^14.0.1", @@ -101,12 +95,10 @@ "zod": "^3.21.4" }, "devDependencies": { - "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@types/command-exists": "^1.2.0", "@types/fs-extra": "^9.0.1", "@types/git-url-parse": "^9.0.0", - "@types/libsodium-wrappers": "^0.7.10", "@types/nunjucks": "^3.1.4", "@types/supertest": "^2.0.8", "@types/zen-observable": "^0.8.0", @@ -115,8 +107,7 @@ "msw": "^1.0.0", "strip-ansi": "^7.1.0", "supertest": "^6.1.3", - "wait-for-expect": "^3.0.2", - "yaml": "^2.0.0" + "wait-for-expect": "^3.0.2" }, "files": [ "dist", diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/util.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/util.ts index 61bd704a0b..7ad21e34ba 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/util.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/util.ts @@ -1,5 +1,5 @@ /* - * Copyright 2021 The Backstage Authors + * Copyright 2023 The Backstage Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,116 +14,7 @@ * limitations under the License. */ -import { InputError } from '@backstage/errors'; -import { isChildPath } from '@backstage/backend-common'; -import { join as joinPath, normalize as normalizePath } from 'path'; -import { ScmIntegrationRegistry } from '@backstage/integration'; - -export const getRepoSourceDirectory = ( - workspacePath: string, - sourcePath: string | undefined, -) => { - if (sourcePath) { - const safeSuffix = normalizePath(sourcePath).replace( - /^(\.\.(\/|\\|$))+/, - '', - ); - const path = joinPath(workspacePath, safeSuffix); - if (!isChildPath(workspacePath, path)) { - throw new Error('Invalid source path'); - } - return path; - } - return workspacePath; -}; -export type RepoSpec = { - repo: string; - host: string; - owner?: string; - organization?: string; - workspace?: string; - project?: string; -}; - -export const parseRepoUrl = ( - repoUrl: string, - integrations: ScmIntegrationRegistry, -): RepoSpec => { - let parsed; - try { - parsed = new URL(`https://${repoUrl}`); - } catch (error) { - throw new InputError( - `Invalid repo URL passed to publisher, got ${repoUrl}, ${error}`, - ); - } - const host = parsed.host; - const owner = parsed.searchParams.get('owner') ?? undefined; - const organization = parsed.searchParams.get('organization') ?? undefined; - const workspace = parsed.searchParams.get('workspace') ?? undefined; - const project = parsed.searchParams.get('project') ?? undefined; - - const type = integrations.byHost(host)?.type; - - if (!type) { - throw new InputError( - `No matching integration configuration for host ${host}, please check your integrations config`, - ); - } - - const repo: string = parsed.searchParams.get('repo')!; - switch (type) { - case 'bitbucket': { - if (host === 'www.bitbucket.org') { - checkRequiredParams(parsed, 'workspace'); - } - checkRequiredParams(parsed, 'project', 'repo'); - break; - } - case 'gitlab': { - // project is the projectID, and if defined, owner and repo won't be needed. - if (!project) { - checkRequiredParams(parsed, 'owner', 'repo'); - } - break; - } - case 'gerrit': { - checkRequiredParams(parsed, 'repo'); - break; - } - default: { - checkRequiredParams(parsed, 'repo', 'owner'); - break; - } - } - - return { host, owner, repo, organization, workspace, project }; -}; -export const isExecutable = (fileMode: number) => { - const executeBitMask = 0o000111; - const res = fileMode & executeBitMask; - return res > 0; -}; - -/** - * This function checks if the required parameters (given as the `params` argument) are present in the URL - * - * @param repoUrl - the URL for the repository - * @param params - a variadic list of URL query parameter names - * - * @throws - * An InputError exception is thrown if any of the required parameters is not in the URL. - * - * @public - */ -function checkRequiredParams(repoUrl: URL, ...params: string[]) { - for (let i = 0; i < params.length; i++) { - if (!repoUrl.searchParams.get(params[i])) { - throw new InputError( - `Invalid repo URL passed to publisher: ${repoUrl.toString()}, missing ${ - params[i] - }`, - ); - } - } -} +// const executeBitMask = 0o000111; +// const res = fileMode & executeBitMask; +// return res > 0; +// }; diff --git a/plugins/scaffolder-node/src/actions/index.ts b/plugins/scaffolder-node/src/actions/index.ts index 47af320ccb..27046bebaf 100644 --- a/plugins/scaffolder-node/src/actions/index.ts +++ b/plugins/scaffolder-node/src/actions/index.ts @@ -25,3 +25,5 @@ export { } from './executeShellCommand'; export { fetchContents, fetchFile } from './fetch'; export { type ActionContext, type TemplateAction } from './types'; +export { initRepoAndPush, commitAndPushRepo } from './repoHelpers'; +export { parseRepoUrl, getRepoSourceDirectory } from './util'; diff --git a/plugins/scaffolder-node/src/actions/repoHelpers.ts b/plugins/scaffolder-node/src/actions/repoHelpers.ts new file mode 100644 index 0000000000..a814ca38ed --- /dev/null +++ b/plugins/scaffolder-node/src/actions/repoHelpers.ts @@ -0,0 +1,127 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Git } from '@backstage/backend-common'; +import { Logger } from 'winston'; + +export async function initRepoAndPush({ + dir, + remoteUrl, + auth, + logger, + defaultBranch = 'master', + commitMessage = 'Initial commit', + gitAuthorInfo, +}: { + dir: string; + remoteUrl: string; + // For use cases where token has to be used with Basic Auth + // it has to be provided as password together with a username + // which may be a fixed value defined by the provider. + auth: { username: string; password: string } | { token: string }; + logger: Logger; + defaultBranch?: string; + commitMessage?: string; + gitAuthorInfo?: { name?: string; email?: string }; +}): Promise<{ commitHash: string }> { + const git = Git.fromAuth({ + ...auth, + logger, + }); + + await git.init({ + dir, + defaultBranch, + }); + + await git.add({ dir, filepath: '.' }); + + // use provided info if possible, otherwise use fallbacks + const authorInfo = { + name: gitAuthorInfo?.name ?? 'Scaffolder', + email: gitAuthorInfo?.email ?? 'scaffolder@backstage.io', + }; + + const commitHash = await git.commit({ + dir, + message: commitMessage, + author: authorInfo, + committer: authorInfo, + }); + await git.addRemote({ + dir, + url: remoteUrl, + remote: 'origin', + }); + + await git.push({ + dir, + remote: 'origin', + }); + + return { commitHash }; +} + +export async function commitAndPushRepo({ + dir, + auth, + logger, + commitMessage, + gitAuthorInfo, + branch = 'master', + remoteRef, +}: { + dir: string; + // For use cases where token has to be used with Basic Auth + // it has to be provided as password together with a username + // which may be a fixed value defined by the provider. + auth: { username: string; password: string } | { token: string }; + logger: Logger; + commitMessage: string; + gitAuthorInfo?: { name?: string; email?: string }; + branch?: string; + remoteRef?: string; +}): Promise<{ commitHash: string }> { + const git = Git.fromAuth({ + ...auth, + logger, + }); + + await git.fetch({ dir }); + await git.checkout({ dir, ref: branch }); + await git.add({ dir, filepath: '.' }); + + // use provided info if possible, otherwise use fallbacks + const authorInfo = { + name: gitAuthorInfo?.name ?? 'Scaffolder', + email: gitAuthorInfo?.email ?? 'scaffolder@backstage.io', + }; + + const commitHash = await git.commit({ + dir, + message: commitMessage, + author: authorInfo, + committer: authorInfo, + }); + + await git.push({ + dir, + remote: 'origin', + remoteRef: remoteRef ?? `refs/heads/${branch}`, + }); + + return { commitHash }; +} diff --git a/plugins/scaffolder-node/src/actions/util.ts b/plugins/scaffolder-node/src/actions/util.ts new file mode 100644 index 0000000000..cdd8512e63 --- /dev/null +++ b/plugins/scaffolder-node/src/actions/util.ts @@ -0,0 +1,112 @@ +/* + * 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 { isChildPath } from '@backstage/backend-common'; +import { join as joinPath, normalize as normalizePath } from 'path'; +import { ScmIntegrationRegistry } from '@backstage/integration'; + +export const getRepoSourceDirectory = ( + workspacePath: string, + sourcePath: string | undefined, +) => { + if (sourcePath) { + const safeSuffix = normalizePath(sourcePath).replace( + /^(\.\.(\/|\\|$))+/, + '', + ); + const path = joinPath(workspacePath, safeSuffix); + if (!isChildPath(workspacePath, path)) { + throw new Error('Invalid source path'); + } + return path; + } + return workspacePath; +}; + +export const parseRepoUrl = ( + repoUrl: string, + integrations: ScmIntegrationRegistry, +): { + repo: string; + host: string; + owner?: string; + organization?: string; + workspace?: string; + project?: string; +} => { + let parsed; + try { + parsed = new URL(`https://${repoUrl}`); + } catch (error) { + throw new InputError( + `Invalid repo URL passed to publisher, got ${repoUrl}, ${error}`, + ); + } + const host = parsed.host; + const owner = parsed.searchParams.get('owner') ?? undefined; + const organization = parsed.searchParams.get('organization') ?? undefined; + const workspace = parsed.searchParams.get('workspace') ?? undefined; + const project = parsed.searchParams.get('project') ?? undefined; + + const type = integrations.byHost(host)?.type; + + if (!type) { + throw new InputError( + `No matching integration configuration for host ${host}, please check your integrations config`, + ); + } + + const repo: string = parsed.searchParams.get('repo')!; + switch (type) { + case 'bitbucket': { + if (host === 'www.bitbucket.org') { + checkRequiredParams(parsed, 'workspace'); + } + checkRequiredParams(parsed, 'project', 'repo'); + break; + } + case 'gitlab': { + // project is the projectID, and if defined, owner and repo won't be needed. + if (!project) { + checkRequiredParams(parsed, 'owner', 'repo'); + } + break; + } + case 'gerrit': { + checkRequiredParams(parsed, 'repo'); + break; + } + default: { + checkRequiredParams(parsed, 'repo', 'owner'); + break; + } + } + + return { host, owner, repo, organization, workspace, project }; +}; + +function checkRequiredParams(repoUrl: URL, ...params: string[]) { + for (let i = 0; i < params.length; i++) { + if (!repoUrl.searchParams.get(params[i])) { + throw new InputError( + `Invalid repo URL passed to publisher: ${repoUrl.toString()}, missing ${ + params[i] + }`, + ); + } + } +} diff --git a/plugins/scaffolder-backend/src/lib/files/deserializeDirectoryContents.test.ts b/plugins/scaffolder-node/src/files/deserializeDirectoryContents.test.ts similarity index 100% rename from plugins/scaffolder-backend/src/lib/files/deserializeDirectoryContents.test.ts rename to plugins/scaffolder-node/src/files/deserializeDirectoryContents.test.ts diff --git a/plugins/scaffolder-backend/src/lib/files/deserializeDirectoryContents.ts b/plugins/scaffolder-node/src/files/deserializeDirectoryContents.ts similarity index 100% rename from plugins/scaffolder-backend/src/lib/files/deserializeDirectoryContents.ts rename to plugins/scaffolder-node/src/files/deserializeDirectoryContents.ts diff --git a/plugins/scaffolder-backend/src/lib/files/index.ts b/plugins/scaffolder-node/src/files/index.ts similarity index 100% rename from plugins/scaffolder-backend/src/lib/files/index.ts rename to plugins/scaffolder-node/src/files/index.ts diff --git a/plugins/scaffolder-backend/src/lib/files/serializeDirectoryContents.test.ts b/plugins/scaffolder-node/src/files/serializeDirectoryContents.test.ts similarity index 100% rename from plugins/scaffolder-backend/src/lib/files/serializeDirectoryContents.test.ts rename to plugins/scaffolder-node/src/files/serializeDirectoryContents.test.ts diff --git a/plugins/scaffolder-backend/src/lib/files/serializeDirectoryContents.ts b/plugins/scaffolder-node/src/files/serializeDirectoryContents.ts similarity index 100% rename from plugins/scaffolder-backend/src/lib/files/serializeDirectoryContents.ts rename to plugins/scaffolder-node/src/files/serializeDirectoryContents.ts diff --git a/plugins/scaffolder-backend/src/lib/files/types.ts b/plugins/scaffolder-node/src/files/types.ts similarity index 100% rename from plugins/scaffolder-backend/src/lib/files/types.ts rename to plugins/scaffolder-node/src/files/types.ts diff --git a/plugins/scaffolder-node/src/index.ts b/plugins/scaffolder-node/src/index.ts index 98691c2afa..0ec492dd32 100644 --- a/plugins/scaffolder-node/src/index.ts +++ b/plugins/scaffolder-node/src/index.ts @@ -22,4 +22,5 @@ export * from './actions'; export * from './tasks'; +export * from './files'; export type { TemplateFilter, TemplateGlobal } from './types'; diff --git a/plugins/scaffolder-react/src/components/types.ts b/plugins/scaffolder-react/src/components/types.ts index 597998bac4..e9ec3bf711 100644 --- a/plugins/scaffolder-react/src/components/types.ts +++ b/plugins/scaffolder-react/src/components/types.ts @@ -23,6 +23,7 @@ import { JsonObject } from '@backstage/types'; export type TemplateGroupFilter = { title?: React.ReactNode; filter: (entity: TemplateEntityV1beta3) => boolean; + sort?: (a: TemplateEntityV1beta3, b: TemplateEntityV1beta3) => number; }; /** From 823dee3b23a41e5c3904dedf5e9262fb9b3e5dd4 Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 6 Dec 2023 12:56:44 +0100 Subject: [PATCH 089/275] chore: create gerrit module Signed-off-by: blam --- .../.eslintrc.js | 1 + .../README.md | 5 + .../package.json | 42 +++ .../src/actions}/gerrit.examples.ts | 0 .../src/actions}/gerrit.test.ts | 5 +- .../src/actions}/gerrit.ts | 9 +- .../src/actions}/gerritReview.test.ts | 9 +- .../src/actions}/gerritReview.ts | 9 +- .../src/actions/index.ts} | 7 +- .../src/index.ts | 23 ++ .../actions/builtin/helpers.test.ts | 319 ------------------ .../src/scaffolder/actions/builtin/helpers.ts | 253 -------------- .../actions/builtin/publish/index.ts | 32 -- .../actions/builtin/publish/util.test.ts | 181 ---------- plugins/scaffolder-node/package.json | 3 + 15 files changed, 98 insertions(+), 800 deletions(-) create mode 100644 plugins/scaffolder-backend-module-gerrit/.eslintrc.js create mode 100644 plugins/scaffolder-backend-module-gerrit/README.md create mode 100644 plugins/scaffolder-backend-module-gerrit/package.json rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/publish => scaffolder-backend-module-gerrit/src/actions}/gerrit.examples.ts (100%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/publish => scaffolder-backend-module-gerrit/src/actions}/gerrit.test.ts (97%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/publish => scaffolder-backend-module-gerrit/src/actions}/gerrit.ts (97%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/publish => scaffolder-backend-module-gerrit/src/actions}/gerritReview.test.ts (93%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/publish => scaffolder-backend-module-gerrit/src/actions}/gerritReview.ts (96%) rename plugins/{scaffolder-backend/src/scaffolder/actions/builtin/publish/util.ts => scaffolder-backend-module-gerrit/src/actions/index.ts} (84%) create mode 100644 plugins/scaffolder-backend-module-gerrit/src/index.ts delete mode 100644 plugins/scaffolder-backend/src/scaffolder/actions/builtin/helpers.test.ts delete mode 100644 plugins/scaffolder-backend/src/scaffolder/actions/builtin/helpers.ts delete mode 100644 plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/index.ts delete mode 100644 plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/util.test.ts diff --git a/plugins/scaffolder-backend-module-gerrit/.eslintrc.js b/plugins/scaffolder-backend-module-gerrit/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/scaffolder-backend-module-gerrit/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/scaffolder-backend-module-gerrit/README.md b/plugins/scaffolder-backend-module-gerrit/README.md new file mode 100644 index 0000000000..f1492f5b35 --- /dev/null +++ b/plugins/scaffolder-backend-module-gerrit/README.md @@ -0,0 +1,5 @@ +# @backstage/plugin-scaffolder-backend-module-gerrit + +The gerrit module for [@backstage/plugin-scaffolder-backend](https://www.npmjs.com/package/@backstage/plugin-scaffolder-backend). + +_This plugin was created through the Backstage CLI_ diff --git a/plugins/scaffolder-backend-module-gerrit/package.json b/plugins/scaffolder-backend-module-gerrit/package.json new file mode 100644 index 0000000000..f3797accb3 --- /dev/null +++ b/plugins/scaffolder-backend-module-gerrit/package.json @@ -0,0 +1,42 @@ +{ + "name": "@backstage/plugin-scaffolder-backend-module-gerrit", + "description": "The gerrit module for @backstage/plugin-scaffolder-backend", + "version": "0.0.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "backend-plugin-module" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/plugin-scaffolder-node": "workspace:^", + "@backstage/errors": "workspace:^", + "@backstage/integration": "workspace:^", + "@backstage/config": "workspace:^", + "node-fetch": "^2.6.7", + "yaml": "^2.0.0" + }, + "devDependencies": { + "@backstage/backend-common": "workspace:^", + "@backstage/backend-test-utils": "workspace:^", + "@backstage/cli": "workspace:^", + "msw": "^1.0.0" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gerrit.examples.ts b/plugins/scaffolder-backend-module-gerrit/src/actions/gerrit.examples.ts similarity index 100% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gerrit.examples.ts rename to plugins/scaffolder-backend-module-gerrit/src/actions/gerrit.examples.ts diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gerrit.test.ts b/plugins/scaffolder-backend-module-gerrit/src/actions/gerrit.test.ts similarity index 97% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gerrit.test.ts rename to plugins/scaffolder-backend-module-gerrit/src/actions/gerrit.test.ts index 73dcc47225..b56c27f59e 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gerrit.test.ts +++ b/plugins/scaffolder-backend-module-gerrit/src/actions/gerrit.test.ts @@ -14,8 +14,9 @@ * limitations under the License. */ -jest.mock('../helpers', () => { +jest.mock('@backstage/plugin-scaffolder-node', () => { return { + ...jest.requireActual('@backstage/plugin-scaffolder-node'), initRepoAndPush: jest.fn().mockResolvedValue({ commitHash: '220f19cc36b551763d157f1b5e4a4b446165dbd6', }), @@ -34,7 +35,7 @@ import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; import { getVoidLogger } from '@backstage/backend-common'; import { PassThrough } from 'stream'; -import { initRepoAndPush } from '../helpers'; +import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; describe('publish:gerrit', () => { const config = new ConfigReader({ diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gerrit.ts b/plugins/scaffolder-backend-module-gerrit/src/actions/gerrit.ts similarity index 97% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gerrit.ts rename to plugins/scaffolder-backend-module-gerrit/src/actions/gerrit.ts index 67ed868c4c..b7369fd5d8 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gerrit.ts +++ b/plugins/scaffolder-backend-module-gerrit/src/actions/gerrit.ts @@ -22,10 +22,13 @@ import { getGerritRequestOptions, ScmIntegrationRegistry, } from '@backstage/integration'; -import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; -import { getRepoSourceDirectory, parseRepoUrl } from './util'; +import { + createTemplateAction, + initRepoAndPush, + getRepoSourceDirectory, + parseRepoUrl, +} from '@backstage/plugin-scaffolder-node'; import fetch, { Response, RequestInit } from 'node-fetch'; -import { initRepoAndPush } from '../helpers'; import { examples } from './gerrit.examples'; const createGerritProject = async ( diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gerritReview.test.ts b/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.test.ts similarity index 93% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gerritReview.test.ts rename to plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.test.ts index 55d7bde5a7..eeae3871ee 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gerritReview.test.ts +++ b/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.test.ts @@ -14,14 +14,19 @@ * limitations under the License. */ -jest.mock('../helpers'); +jest.mock('@backstage/plugin-scaffolder-node', () => { + return { + ...jest.requireActual('@backstage/plugin-scaffolder-node'), + commitAndPushRepo: jest.fn(), + }; +}); import { createPublishGerritReviewAction } from './gerritReview'; import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; import { getVoidLogger } from '@backstage/backend-common'; import { PassThrough } from 'stream'; -import { commitAndPushRepo } from '../helpers'; +import { commitAndPushRepo } from '@backstage/plugin-scaffolder-node'; describe('publish:gerrit:review', () => { const config = new ConfigReader({ diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gerritReview.ts b/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.ts similarity index 96% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gerritReview.ts rename to plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.ts index 73e74f5cbc..bd8d0321ab 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gerritReview.ts +++ b/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.ts @@ -18,9 +18,12 @@ import crypto from 'crypto'; import { InputError } from '@backstage/errors'; import { Config } from '@backstage/config'; import { ScmIntegrationRegistry } from '@backstage/integration'; -import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; -import { getRepoSourceDirectory, parseRepoUrl } from './util'; -import { commitAndPushRepo } from '../helpers'; +import { + createTemplateAction, + commitAndPushRepo, + getRepoSourceDirectory, + parseRepoUrl, +} from '@backstage/plugin-scaffolder-node'; const generateGerritChangeId = (): string => { const changeId = crypto.randomBytes(20).toString('hex'); diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/util.ts b/plugins/scaffolder-backend-module-gerrit/src/actions/index.ts similarity index 84% rename from plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/util.ts rename to plugins/scaffolder-backend-module-gerrit/src/actions/index.ts index 7ad21e34ba..1918679320 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/util.ts +++ b/plugins/scaffolder-backend-module-gerrit/src/actions/index.ts @@ -13,8 +13,5 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -// const executeBitMask = 0o000111; -// const res = fileMode & executeBitMask; -// return res > 0; -// }; +export * from './gerrit'; +export * from './gerritReview'; diff --git a/plugins/scaffolder-backend-module-gerrit/src/index.ts b/plugins/scaffolder-backend-module-gerrit/src/index.ts new file mode 100644 index 0000000000..21fdd116e7 --- /dev/null +++ b/plugins/scaffolder-backend-module-gerrit/src/index.ts @@ -0,0 +1,23 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * The gerrit module for @backstage/plugin-scaffolder-backend. + * + * @packageDocumentation + */ + +export * from './actions'; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/helpers.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/helpers.test.ts deleted file mode 100644 index 7362e99892..0000000000 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/helpers.test.ts +++ /dev/null @@ -1,319 +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 { Git, getVoidLogger } from '@backstage/backend-common'; -import { commitAndPushRepo, entityRefToName, initRepoAndPush } from './helpers'; - -jest.mock('@backstage/backend-common', () => ({ - Git: { - fromAuth: jest.fn().mockReturnValue({ - init: jest.fn(), - add: jest.fn(), - checkout: jest.fn(), - commit: jest - .fn() - .mockResolvedValue('220f19cc36b551763d157f1b5e4a4b446165dbd6'), - fetch: jest.fn(), - addRemote: jest.fn(), - push: jest.fn(), - }), - }, - getVoidLogger: jest.requireActual('@backstage/backend-common').getVoidLogger, -})); - -const mockedGit = Git.fromAuth({ - logger: getVoidLogger(), -}); - -describe('initRepoAndPush', () => { - afterEach(() => { - jest.clearAllMocks(); - }); - - describe('with minimal parameters', () => { - beforeEach(async () => { - await initRepoAndPush({ - dir: '/test/repo/dir/', - remoteUrl: 'git@github.com:test/repo.git', - auth: { - username: 'test-user', - password: 'test-password', - }, - logger: getVoidLogger(), - }); - }); - - it('initializes the repo', () => { - expect(mockedGit.init).toHaveBeenCalledWith({ - dir: '/test/repo/dir/', - defaultBranch: 'master', - }); - }); - - it('stages all files in the repo', () => { - expect(mockedGit.add).toHaveBeenCalledWith({ - dir: '/test/repo/dir/', - filepath: '.', - }); - }); - - it('creates an initial commit', () => { - expect(mockedGit.commit).toHaveBeenCalledWith({ - dir: '/test/repo/dir/', - message: 'Initial commit', - author: { - name: 'Scaffolder', - email: 'scaffolder@backstage.io', - }, - committer: { - name: 'Scaffolder', - email: 'scaffolder@backstage.io', - }, - }); - }); - - it('adds the appropriate remote', () => { - expect(mockedGit.addRemote).toHaveBeenCalledWith({ - dir: '/test/repo/dir/', - url: 'git@github.com:test/repo.git', - remote: 'origin', - }); - }); - - it('pushes to the remote', () => { - expect(mockedGit.push).toHaveBeenCalledWith({ - dir: '/test/repo/dir/', - remote: 'origin', - }); - }); - }); - - it('with token', async () => { - await initRepoAndPush({ - dir: '/test/repo/dir/', - remoteUrl: 'git@github.com:test/repo.git', - auth: { - token: 'test-token', - }, - logger: getVoidLogger(), - }); - - expect(mockedGit.init).toHaveBeenCalledWith({ - dir: '/test/repo/dir/', - defaultBranch: 'master', - }); - }); - - it('allows overriding the default branch', async () => { - await initRepoAndPush({ - dir: '/test/repo/dir/', - defaultBranch: 'trunk', - remoteUrl: 'git@github.com:test/repo.git', - auth: { - username: 'test-user', - password: 'test-password', - }, - logger: getVoidLogger(), - }); - - expect(mockedGit.init).toHaveBeenCalledWith({ - dir: '/test/repo/dir/', - defaultBranch: 'trunk', - }); - }); - - it('allows overriding the author', async () => { - await initRepoAndPush({ - dir: '/test/repo/dir/', - gitAuthorInfo: { - name: 'Custom Scaffolder Author', - email: 'scaffolder@example.org', - }, - remoteUrl: 'git@github.com:test/repo.git', - auth: { - username: 'test-user', - password: 'test-password', - }, - logger: getVoidLogger(), - }); - - expect(mockedGit.commit).toHaveBeenCalledWith({ - dir: '/test/repo/dir/', - message: 'Initial commit', - author: { - name: 'Custom Scaffolder Author', - email: 'scaffolder@example.org', - }, - committer: { - name: 'Custom Scaffolder Author', - email: 'scaffolder@example.org', - }, - }); - }); -}); - -describe('commitAndPushRepo', () => { - afterEach(() => { - jest.clearAllMocks(); - }); - - describe('with minimal parameters', () => { - beforeEach(async () => { - await commitAndPushRepo({ - dir: '/test/repo/dir/', - auth: { - username: 'test-user', - password: 'test-password', - }, - logger: getVoidLogger(), - commitMessage: 'commit message', - }); - }); - - it('fetches commits', () => { - expect(mockedGit.fetch).toHaveBeenCalledWith({ - dir: '/test/repo/dir/', - }); - }); - - it('checkouts to master', () => { - expect(mockedGit.checkout).toHaveBeenCalledWith({ - dir: '/test/repo/dir/', - ref: 'master', - }); - }); - - it('stages all files in the repo', () => { - expect(mockedGit.add).toHaveBeenCalledWith({ - dir: '/test/repo/dir/', - filepath: '.', - }); - }); - - it('creates a commit', () => { - expect(mockedGit.commit).toHaveBeenCalledWith({ - dir: '/test/repo/dir/', - message: 'commit message', - author: { - name: 'Scaffolder', - email: 'scaffolder@backstage.io', - }, - committer: { - name: 'Scaffolder', - email: 'scaffolder@backstage.io', - }, - }); - }); - - it('pushes to the remote', () => { - expect(mockedGit.push).toHaveBeenCalledWith({ - dir: '/test/repo/dir/', - remote: 'origin', - remoteRef: 'refs/heads/master', - }); - }); - }); - - it('allows overriding the default branch', async () => { - await commitAndPushRepo({ - dir: '/test/repo/dir/', - auth: { - username: 'test-user', - password: 'test-password', - }, - logger: getVoidLogger(), - commitMessage: 'commit message', - branch: 'otherbranch', - }); - - expect(mockedGit.checkout).toHaveBeenCalledWith({ - dir: '/test/repo/dir/', - ref: 'otherbranch', - }); - expect(mockedGit.push).toHaveBeenCalledWith({ - dir: '/test/repo/dir/', - remote: 'origin', - remoteRef: 'refs/heads/otherbranch', - }); - }); - - it('allows overriding the remote ref', async () => { - await commitAndPushRepo({ - dir: '/test/repo/dir/', - auth: { - username: 'test-user', - password: 'test-password', - }, - logger: getVoidLogger(), - commitMessage: 'commit message', - remoteRef: 'refs/for/master', - }); - - expect(mockedGit.checkout).toHaveBeenCalledWith({ - dir: '/test/repo/dir/', - ref: 'master', - }); - expect(mockedGit.push).toHaveBeenCalledWith({ - dir: '/test/repo/dir/', - remote: 'origin', - remoteRef: 'refs/for/master', - }); - }); - - it('allows overriding the author', async () => { - await commitAndPushRepo({ - dir: '/test/repo/dir/', - commitMessage: 'commit message', - gitAuthorInfo: { - name: 'Custom Scaffolder Author', - email: 'scaffolder@example.org', - }, - auth: { - username: 'test-user', - password: 'test-password', - }, - logger: getVoidLogger(), - branch: 'master', - }); - - expect(mockedGit.commit).toHaveBeenCalledWith({ - dir: '/test/repo/dir/', - message: 'commit message', - author: { - name: 'Custom Scaffolder Author', - email: 'scaffolder@example.org', - }, - committer: { - name: 'Custom Scaffolder Author', - email: 'scaffolder@example.org', - }, - }); - }); -}); - -describe('entityRefToName', () => { - it.each([ - 'user:default/catpants', - 'group:default/catpants', - 'user:catpants', - 'default/catpants', - 'user:custom/catpants', - 'group:custom/catpants', - 'catpants', - ])('should parse: "%s"', (entityName: string) => { - expect(entityRefToName(entityName)).toEqual('catpants'); - }); -}); diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/helpers.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/helpers.ts deleted file mode 100644 index 5ac92128ca..0000000000 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/helpers.ts +++ /dev/null @@ -1,253 +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 { Git } from '@backstage/backend-common'; -import { Config } from '@backstage/config'; -import { assertError } from '@backstage/errors'; -import { Octokit } from 'octokit'; -import { Logger } from 'winston'; - -export async function initRepoAndPush({ - dir, - remoteUrl, - auth, - logger, - defaultBranch = 'master', - commitMessage = 'Initial commit', - gitAuthorInfo, -}: { - dir: string; - remoteUrl: string; - // For use cases where token has to be used with Basic Auth - // it has to be provided as password together with a username - // which may be a fixed value defined by the provider. - auth: { username: string; password: string } | { token: string }; - logger: Logger; - defaultBranch?: string; - commitMessage?: string; - gitAuthorInfo?: { name?: string; email?: string }; -}): Promise<{ commitHash: string }> { - const git = Git.fromAuth({ - ...auth, - logger, - }); - - await git.init({ - dir, - defaultBranch, - }); - - await git.add({ dir, filepath: '.' }); - - // use provided info if possible, otherwise use fallbacks - const authorInfo = { - name: gitAuthorInfo?.name ?? 'Scaffolder', - email: gitAuthorInfo?.email ?? 'scaffolder@backstage.io', - }; - - const commitHash = await git.commit({ - dir, - message: commitMessage, - author: authorInfo, - committer: authorInfo, - }); - await git.addRemote({ - dir, - url: remoteUrl, - remote: 'origin', - }); - - await git.push({ - dir, - remote: 'origin', - }); - - return { commitHash }; -} - -export async function commitAndPushRepo({ - dir, - auth, - logger, - commitMessage, - gitAuthorInfo, - branch = 'master', - remoteRef, -}: { - dir: string; - // For use cases where token has to be used with Basic Auth - // it has to be provided as password together with a username - // which may be a fixed value defined by the provider. - auth: { username: string; password: string } | { token: string }; - logger: Logger; - commitMessage: string; - gitAuthorInfo?: { name?: string; email?: string }; - branch?: string; - remoteRef?: string; -}): Promise<{ commitHash: string }> { - const git = Git.fromAuth({ - ...auth, - logger, - }); - - await git.fetch({ dir }); - await git.checkout({ dir, ref: branch }); - await git.add({ dir, filepath: '.' }); - - // use provided info if possible, otherwise use fallbacks - const authorInfo = { - name: gitAuthorInfo?.name ?? 'Scaffolder', - email: gitAuthorInfo?.email ?? 'scaffolder@backstage.io', - }; - - const commitHash = await git.commit({ - dir, - message: commitMessage, - author: authorInfo, - committer: authorInfo, - }); - - await git.push({ - dir, - remote: 'origin', - remoteRef: remoteRef ?? `refs/heads/${branch}`, - }); - - return { commitHash }; -} - -type BranchProtectionOptions = { - client: Octokit; - owner: string; - repoName: string; - logger: Logger; - requireCodeOwnerReviews: boolean; - requiredStatusCheckContexts?: string[]; - bypassPullRequestAllowances?: { - users?: string[]; - teams?: string[]; - apps?: string[]; - }; - requiredApprovingReviewCount?: number; - restrictions?: { - users: string[]; - teams: string[]; - apps?: string[]; - }; - requireBranchesToBeUpToDate?: boolean; - requiredConversationResolution?: boolean; - defaultBranch?: string; - enforceAdmins?: boolean; - dismissStaleReviews?: boolean; - requiredCommitSigning?: boolean; -}; - -export const enableBranchProtectionOnDefaultRepoBranch = async ({ - repoName, - client, - owner, - logger, - requireCodeOwnerReviews, - bypassPullRequestAllowances, - requiredApprovingReviewCount, - restrictions, - requiredStatusCheckContexts = [], - requireBranchesToBeUpToDate = true, - requiredConversationResolution = false, - defaultBranch = 'master', - enforceAdmins = true, - dismissStaleReviews = false, - requiredCommitSigning = false, -}: BranchProtectionOptions): Promise => { - const tryOnce = async () => { - try { - await client.rest.repos.updateBranchProtection({ - mediaType: { - /** - * 👇 we need this preview because allowing a custom - * reviewer count on branch protection is a preview - * feature - * - * More here: https://docs.github.com/en/rest/overview/api-previews#require-multiple-approving-reviews - */ - previews: ['luke-cage-preview'], - }, - owner, - repo: repoName, - branch: defaultBranch, - required_status_checks: { - strict: requireBranchesToBeUpToDate, - contexts: requiredStatusCheckContexts, - }, - restrictions: restrictions ?? null, - enforce_admins: enforceAdmins, - required_pull_request_reviews: { - required_approving_review_count: requiredApprovingReviewCount, - require_code_owner_reviews: requireCodeOwnerReviews, - bypass_pull_request_allowances: bypassPullRequestAllowances, - dismiss_stale_reviews: dismissStaleReviews, - }, - required_conversation_resolution: requiredConversationResolution, - }); - - if (requiredCommitSigning) { - await client.rest.repos.createCommitSignatureProtection({ - owner, - repo: repoName, - branch: defaultBranch, - }); - } - } catch (e) { - assertError(e); - if ( - e.message.includes( - 'Upgrade to GitHub Pro or make this repository public to enable this feature', - ) - ) { - logger.warn( - 'Branch protection was not enabled as it requires GitHub Pro for private repositories', - ); - } else { - throw e; - } - } - }; - - try { - await tryOnce(); - } catch (e) { - if (!e.message.includes('Branch not found')) { - throw e; - } - - // GitHub has eventual consistency. Fail silently, wait, and try again. - await new Promise(resolve => setTimeout(resolve, 600)); - await tryOnce(); - } -}; - -export function getGitCommitMessage( - gitCommitMessage: string | undefined, - config: Config, -): string | undefined { - return gitCommitMessage - ? gitCommitMessage - : config.getOptionalString('scaffolder.defaultCommitMessage'); -} - -export function entityRefToName(name: string): string { - return name.replace(/^.*[:/]/g, ''); -} diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/index.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/index.ts deleted file mode 100644 index bed3a2316c..0000000000 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/index.ts +++ /dev/null @@ -1,32 +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. - */ - -export { createPublishAzureAction } from './azure'; -export { createPublishBitbucketAction } from './bitbucket'; -export { createPublishBitbucketCloudAction } from './bitbucketCloud'; -export { createPublishBitbucketServerAction } from './bitbucketServer'; -export { createPublishBitbucketServerPullRequestAction } from './bitbucketServerPullRequest'; -export { createPublishGerritAction } from './gerrit'; -export { createPublishGerritReviewAction } from './gerritReview'; -export { createPublishGithubAction } from './github'; -export { createPublishGithubPullRequestAction } from './githubPullRequest'; -export type { - CreateGithubPullRequestClientFactoryInput, - CreateGithubPullRequestActionOptions, - OctokitWithPullRequestPluginClient, -} from './githubPullRequest'; -export { createPublishGitlabAction } from './gitlab'; -export { createPublishGitlabMergeRequestAction } from './gitlabMergeRequest'; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/util.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/util.test.ts deleted file mode 100644 index 5446109056..0000000000 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/util.test.ts +++ /dev/null @@ -1,181 +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 path from 'path'; -import { getRepoSourceDirectory, isExecutable, parseRepoUrl } from './util'; -import { ScmIntegrations } from '@backstage/integration'; -import { ConfigReader } from '@backstage/config'; - -describe('getRepoSourceDirectory', () => { - it('should return workspace root if no sub folder is given', () => { - expect( - getRepoSourceDirectory(path.join('/', 'var', 'workspace'), undefined), - ).toEqual(path.join('/', 'var', 'workspace')); - }); - - it('should return path in workspace if sub folder is given', () => { - expect( - getRepoSourceDirectory( - path.join('/', 'var', 'workspace'), - path.join('path', 'of', 'subfolder'), - ), - ).toEqual(path.join('/', 'var', 'workspace', 'path', 'of', 'subfolder')); - }); - - it('should not allow traversal outside the workspace root', () => { - // We have to construct the path manually here, as path.join would mitigate the path traversal - expect( - getRepoSourceDirectory( - path.join('/', 'var', 'workspace'), - `..${path.sep}secret`, - ), - ).toEqual(path.join('/', 'var', 'workspace', 'secret')); - expect( - getRepoSourceDirectory( - path.join('/', 'var', 'workspace'), - `.${path.sep}path${path.sep}..${path.sep}..${path.sep}secret`, - ), - ).toEqual(path.join('/', 'var', 'workspace', 'secret')); - expect( - getRepoSourceDirectory( - path.join('/', 'var', 'workspace'), - path.join('/', 'absolute', 'secret'), - ), - ).toEqual(path.join('/', 'var', 'workspace', 'absolute', 'secret')); - }); -}); - -describe('isExecutable', () => { - it('should return true for file mode 777', () => { - expect(isExecutable(0o100777)).toBe(true); - }); - it('should return true for file mode 775', () => { - expect(isExecutable(0o100775)).toBe(true); - }); - it('should return true for file mode 755', () => { - expect(isExecutable(0o100755)).toBe(true); - }); - it('should return true for file mode 700', () => { - expect(isExecutable(0o100700)).toBe(true); - }); - it('should return true for file mode 770', () => { - expect(isExecutable(0o100770)).toBe(true); - }); - it('should return true for file mode 670', () => { - expect(isExecutable(0o100670)).toBe(true); - }); - it('should return false for file mode 644', () => { - expect(isExecutable(0o100644)).toBe(false); - }); - it('should return false for file mode 600', () => { - expect(isExecutable(0o100600)).toBe(false); - }); - it('should return false for file mode 640', () => { - expect(isExecutable(0o100640)).toBe(false); - }); -}); - -describe('parseRepoUrl', () => { - const config = new ConfigReader({ - integrations: { - gitlab: [ - { - host: 'www.gitlab.com', - token: 'token', - apiBaseUrl: 'https://api.gitlab.com', - }, - ], - bitbucket: [ - { - host: 'www.bitbucket.net', - apiBaseUrl: 'https://api.hosted.bitbucket.net', - }, - { - host: 'www.bitbucket.org', - username: 'username', - appPassword: 'password', - apiBaseUrl: 'https://api.hosted.bitbucket.org', - }, - ], - }, - }); - const integrations = ScmIntegrations.fromConfig(config); - it('should throw an exception if no parameters are passed (gitlab)', () => { - expect(() => parseRepoUrl('www.gitlab.com', integrations)).toThrow( - 'Invalid repo URL passed to publisher: https://www.gitlab.com/, missing owner', - ); - }); - it('should return the project ID in the `project` parameter (gitlab)', () => { - expect( - parseRepoUrl('www.gitlab.com?project=234', integrations), - ).toStrictEqual({ - host: 'www.gitlab.com', - organization: undefined, - owner: undefined, - project: '234', - repo: null, - workspace: undefined, - }); - }); - it('should throw an exception if the repo parameter is missing, but owner parameter is set', () => { - expect(() => - parseRepoUrl('www.gitlab.com?owner=owner', integrations), - ).toThrow( - 'Invalid repo URL passed to publisher: https://www.gitlab.com/?owner=owner, missing repo', - ); - }); - it('should throw an exception if the owner parameter is missing, but repo parameter is set (gitlab)', () => { - expect(() => - parseRepoUrl('www.gitlab.com?repo=repo', integrations), - ).toThrow( - 'Invalid repo URL passed to publisher: https://www.gitlab.com/?repo=repo, missing owner', - ); - }); - it('should return the workspace, project and repo (bitbucket.org)', () => { - expect( - parseRepoUrl( - 'www.bitbucket.org?project=project&workspace=workspace&repo=repo', - integrations, - ), - ).toStrictEqual({ - host: 'www.bitbucket.org', - organization: undefined, - owner: undefined, - project: 'project', - repo: 'repo', - workspace: 'workspace', - }); - }); - it('should return the project and repo (another bitbucket instance)', () => { - expect( - parseRepoUrl('www.bitbucket.net?project=project&repo=repo', integrations), - ).toStrictEqual({ - host: 'www.bitbucket.net', - organization: undefined, - owner: undefined, - project: 'project', - repo: 'repo', - workspace: undefined, - }); - }); - it('should throw an exception if the workspace parameter is missing for bitbucket.org instance (bitbucket.org)', () => { - expect(() => - parseRepoUrl('www.bitbucket.org?project=project&repo=repo', integrations), - ).toThrow( - 'Invalid repo URL passed to publisher: https://www.bitbucket.org/?project=project&repo=repo, missing workspace', - ); - }); -}); diff --git a/plugins/scaffolder-node/package.json b/plugins/scaffolder-node/package.json index 5f5702a035..877a465052 100644 --- a/plugins/scaffolder-node/package.json +++ b/plugins/scaffolder-node/package.json @@ -50,12 +50,15 @@ "@backstage/plugin-scaffolder-common": "workspace:^", "@backstage/types": "workspace:^", "fs-extra": "10.1.0", + "globby": "^11.0.0", "jsonschema": "^1.2.6", + "p-limit": "^3.1.0", "winston": "^3.2.1", "zod": "^3.21.4", "zod-to-json-schema": "^3.20.4" }, "devDependencies": { + "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@backstage/config": "workspace:^" }, From ff5c9a27c53aa7f9df9846437ccc250068ed27b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Wed, 6 Dec 2023 13:26:23 +0100 Subject: [PATCH 090/275] Update microsite/data/plugins/open-dora.yaml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- microsite/data/plugins/open-dora.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/microsite/data/plugins/open-dora.yaml b/microsite/data/plugins/open-dora.yaml index 9eb9c3520f..16b4c63969 100644 --- a/microsite/data/plugins/open-dora.yaml +++ b/microsite/data/plugins/open-dora.yaml @@ -5,6 +5,6 @@ authorUrl: https://www.devoteam.com/ category: Monitoring description: View DORA metrics within Backstage using DevLake. documentation: https://github.com/DevoteamNL/opendora/tree/main/backstage-plugin/plugins/open-dora#readme -iconUrl: img/open-dora-icon.png +iconUrl: /img/open-dora-icon.png npmPackageName: '@devoteam-nl/open-dora-backstage-plugin' addedDate: '2023-11-29' From 480d3b209d49a34bea36e1e2e731d0ee61db8856 Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 6 Dec 2023 13:35:12 +0100 Subject: [PATCH 091/275] chore: update imports Signed-off-by: blam --- packages/cli/src/lib/version.ts | 4 +- plugins/scaffolder-backend/package.json | 5 + .../src/lib/templating/filters.ts | 2 +- .../actions/builtin/createBuiltinActions.ts | 21 +++- .../src/scaffolder/actions/builtin/index.ts | 2 - .../src/scaffolder/dryrun/createDryRunner.ts | 11 +-- yarn.lock | 99 ++++++++++++++++--- 7 files changed, 116 insertions(+), 28 deletions(-) diff --git a/packages/cli/src/lib/version.ts b/packages/cli/src/lib/version.ts index 96b42fcfb7..9c19a3a8c4 100644 --- a/packages/cli/src/lib/version.ts +++ b/packages/cli/src/lib/version.ts @@ -44,8 +44,8 @@ import { version as coreComponents } from '../../../../packages/core-components/ import { version as corePluginApi } from '../../../../packages/core-plugin-api/package.json'; import { version as devUtils } from '../../../../packages/dev-utils/package.json'; import { version as testUtils } from '../../../../packages/test-utils/package.json'; +import { version as scaffolderNode } from '../../../../plugins/scaffolder-node/package.json'; import { version as theme } from '../../../../packages/theme/package.json'; -import { version as scaffolderBackend } from '../../../../plugins/scaffolder-backend/package.json'; export const packageVersions: Record = { '@backstage/backend-common': backendCommon, @@ -59,7 +59,7 @@ export const packageVersions: Record = { '@backstage/dev-utils': devUtils, '@backstage/test-utils': testUtils, '@backstage/theme': theme, - '@backstage/plugin-scaffolder-backend': scaffolderBackend, + '@backstage/plugin-scaffolder-node': scaffolderNode, }; export function findVersion() { diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index d89fc2f3ca..17f293f313 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -61,6 +61,11 @@ "@backstage/plugin-catalog-node": "workspace:^", "@backstage/plugin-permission-common": "workspace:^", "@backstage/plugin-permission-node": "workspace:^", + "@backstage/plugin-scaffolder-backend-module-azure": "workspace:^", + "@backstage/plugin-scaffolder-backend-module-bitbucket": "workspace:^", + "@backstage/plugin-scaffolder-backend-module-gerrit": "workspace:^", + "@backstage/plugin-scaffolder-backend-module-github": "workspace:^", + "@backstage/plugin-scaffolder-backend-module-gitlab": "workspace:^", "@backstage/plugin-scaffolder-common": "workspace:^", "@backstage/plugin-scaffolder-node": "workspace:^", "@backstage/types": "workspace:^", diff --git a/plugins/scaffolder-backend/src/lib/templating/filters.ts b/plugins/scaffolder-backend/src/lib/templating/filters.ts index 7808d6d136..21b43a6164 100644 --- a/plugins/scaffolder-backend/src/lib/templating/filters.ts +++ b/plugins/scaffolder-backend/src/lib/templating/filters.ts @@ -17,7 +17,7 @@ import { parseEntityRef } from '@backstage/catalog-model'; import { ScmIntegrations } from '@backstage/integration'; import type { JsonObject, JsonValue } from '@backstage/types'; import { TemplateFilter } from '..'; -import { parseRepoUrl } from '../../scaffolder/actions/builtin/publish/util'; +import { parseRepoUrl } from '@backstage/plugin-scaffolder-node'; import get from 'lodash/get'; export const createDefaultFilters = ({ diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts index 4dcd2c2a0d..6fc50c6453 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts @@ -48,20 +48,28 @@ import { createGithubRepoCreateAction, createGithubRepoPushAction, createGithubWebhookAction, -} from './github'; + createPublishGithubAction, + createPublishGithubPullRequestAction, +} from '@backstage/plugin-scaffolder-backend-module-github'; + +import { createPublishAzureAction } from '@backstage/plugin-scaffolder-backend-module-azure'; + import { - createPublishAzureAction, createPublishBitbucketAction, createPublishBitbucketCloudAction, createPublishBitbucketServerAction, createPublishBitbucketServerPullRequestAction, +} from '@backstage/plugin-scaffolder-backend-module-bitbucket'; + +import { createPublishGerritAction, createPublishGerritReviewAction, - createPublishGithubAction, - createPublishGithubPullRequestAction, +} from '@backstage/plugin-scaffolder-backend-module-gerrit'; + +import { createPublishGitlabAction, createPublishGitlabMergeRequestAction, -} from './publish'; +} from '@backstage/plugin-scaffolder-backend-module-gitlab'; /** * The options passed to {@link createBuiltinActions} @@ -96,8 +104,11 @@ export interface CreateBuiltInActionsOptions { * A function to generate create a list of default actions that the scaffolder provides. * Is called internally in the default setup, but can be used when adding your own actions or overriding the default ones * + * TODO(blam): version 2 of the scaffolder shouldn't ship with the additional modules. We should ship the basics, and let people install + * modules for the providers they want to use. * @public * @returns A list of actions that can be used in the scaffolder + * */ export const createBuiltinActions = ( options: CreateBuiltInActionsOptions, diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/index.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/index.ts index 7ab98482ff..6fdbb24484 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/index.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/index.ts @@ -19,5 +19,3 @@ export * from './createBuiltinActions'; export * from './debug'; export * from './fetch'; export * from './filesystem'; -export * from './publish'; -export * from './github'; diff --git a/plugins/scaffolder-backend/src/scaffolder/dryrun/createDryRunner.ts b/plugins/scaffolder-backend/src/scaffolder/dryrun/createDryRunner.ts index 655c485a6d..e202111d79 100644 --- a/plugins/scaffolder-backend/src/scaffolder/dryrun/createDryRunner.ts +++ b/plugins/scaffolder-backend/src/scaffolder/dryrun/createDryRunner.ts @@ -21,20 +21,19 @@ import { v4 as uuid } from 'uuid'; import { pathToFileURL } from 'url'; import { Logger } from 'winston'; import { + createTemplateAction, + TaskSecrets, + TemplateFilter, + TemplateGlobal, deserializeDirectoryContents, SerializedFile, serializeDirectoryContents, -} from '../../lib/files'; -import { TemplateFilter, TemplateGlobal } from '../../lib'; +} from '@backstage/plugin-scaffolder-node'; import { TemplateActionRegistry } from '../actions'; import { NunjucksWorkflowRunner } from '../tasks/NunjucksWorkflowRunner'; import { DecoratedActionsRegistry } from './DecoratedActionsRegistry'; import fs from 'fs-extra'; import { resolveSafeChildPath } from '@backstage/backend-common'; -import { - createTemplateAction, - TaskSecrets, -} from '@backstage/plugin-scaffolder-node'; import { PermissionEvaluator } from '@backstage/plugin-permission-common'; interface DryRunInput { diff --git a/yarn.lock b/yarn.lock index 2fd28cd48c..cc201b6204 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8611,6 +8611,38 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-scaffolder-backend-module-azure@workspace:^, @backstage/plugin-scaffolder-backend-module-azure@workspace:plugins/scaffolder-backend-module-azure": + version: 0.0.0-use.local + resolution: "@backstage/plugin-scaffolder-backend-module-azure@workspace:plugins/scaffolder-backend-module-azure" + dependencies: + "@backstage/backend-common": "workspace:^" + "@backstage/cli": "workspace:^" + "@backstage/config": "workspace:^" + "@backstage/errors": "workspace:^" + "@backstage/integration": "workspace:^" + "@backstage/plugin-scaffolder-node": "workspace:^" + azure-devops-node-api: ^11.0.1 + yaml: ^2.0.0 + languageName: unknown + linkType: soft + +"@backstage/plugin-scaffolder-backend-module-bitbucket@workspace:^, @backstage/plugin-scaffolder-backend-module-bitbucket@workspace:plugins/scaffolder-backend-module-bitbucket": + version: 0.0.0-use.local + resolution: "@backstage/plugin-scaffolder-backend-module-bitbucket@workspace:plugins/scaffolder-backend-module-bitbucket" + dependencies: + "@backstage/backend-common": "workspace:^" + "@backstage/backend-test-utils": "workspace:^" + "@backstage/cli": "workspace:^" + "@backstage/config": "workspace:^" + "@backstage/errors": "workspace:^" + "@backstage/integration": "workspace:^" + "@backstage/plugin-scaffolder-node": "workspace:^" + msw: ^1.0.0 + node-fetch: ^2.6.7 + yaml: ^2.0.0 + languageName: unknown + linkType: soft + "@backstage/plugin-scaffolder-backend-module-confluence-to-markdown@workspace:^, @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@workspace:plugins/scaffolder-backend-module-confluence-to-markdown": version: 0.0.0-use.local resolution: "@backstage/plugin-scaffolder-backend-module-confluence-to-markdown@workspace:plugins/scaffolder-backend-module-confluence-to-markdown" @@ -8655,18 +8687,61 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-scaffolder-backend-module-gitlab@workspace:plugins/scaffolder-backend-module-gitlab": +"@backstage/plugin-scaffolder-backend-module-gerrit@workspace:^, @backstage/plugin-scaffolder-backend-module-gerrit@workspace:plugins/scaffolder-backend-module-gerrit": + version: 0.0.0-use.local + resolution: "@backstage/plugin-scaffolder-backend-module-gerrit@workspace:plugins/scaffolder-backend-module-gerrit" + dependencies: + "@backstage/backend-common": "workspace:^" + "@backstage/backend-test-utils": "workspace:^" + "@backstage/cli": "workspace:^" + "@backstage/config": "workspace:^" + "@backstage/errors": "workspace:^" + "@backstage/integration": "workspace:^" + "@backstage/plugin-scaffolder-node": "workspace:^" + msw: ^1.0.0 + node-fetch: ^2.6.7 + yaml: ^2.0.0 + languageName: unknown + linkType: soft + +"@backstage/plugin-scaffolder-backend-module-github@workspace:^, @backstage/plugin-scaffolder-backend-module-github@workspace:plugins/scaffolder-backend-module-github": + version: 0.0.0-use.local + resolution: "@backstage/plugin-scaffolder-backend-module-github@workspace:plugins/scaffolder-backend-module-github" + dependencies: + "@backstage/backend-common": "workspace:^" + "@backstage/backend-test-utils": "workspace:^" + "@backstage/cli": "workspace:^" + "@backstage/config": "workspace:^" + "@backstage/errors": "workspace:^" + "@backstage/integration": "workspace:^" + "@backstage/plugin-scaffolder-node": "workspace:^" + "@octokit/webhooks": ^10.0.0 + "@types/libsodium-wrappers": ^0.7.10 + fs-extra: 10.1.0 + jest-when: ^3.1.0 + jsonschema: ^1.2.6 + libsodium-wrappers: ^0.7.11 + octokit: ^2.0.0 + octokit-plugin-create-pull-request: ^3.10.0 + winston: ^3.2.1 + yaml: ^2.0.0 + languageName: unknown + linkType: soft + +"@backstage/plugin-scaffolder-backend-module-gitlab@workspace:^, @backstage/plugin-scaffolder-backend-module-gitlab@workspace:plugins/scaffolder-backend-module-gitlab": version: 0.0.0-use.local resolution: "@backstage/plugin-scaffolder-backend-module-gitlab@workspace:plugins/scaffolder-backend-module-gitlab" dependencies: "@backstage/backend-common": "workspace:^" + "@backstage/backend-test-utils": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" "@backstage/core-app-api": "workspace:^" "@backstage/errors": "workspace:^" "@backstage/integration": "workspace:^" "@backstage/plugin-scaffolder-node": "workspace:^" - "@gitbeaker/node": ^35.8.0 + "@gitbeaker/core": ^35.8.0 + "@gitbeaker/node": ^35.1.0 yaml: ^2.0.0 zod: ^3.21.4 languageName: unknown @@ -8729,7 +8804,6 @@ __metadata: "@backstage/backend-common": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-tasks": "workspace:^" - "@backstage/backend-test-utils": "workspace:^" "@backstage/catalog-client": "workspace:^" "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" @@ -8743,17 +8817,18 @@ __metadata: "@backstage/plugin-catalog-node": "workspace:^" "@backstage/plugin-permission-common": "workspace:^" "@backstage/plugin-permission-node": "workspace:^" + "@backstage/plugin-scaffolder-backend-module-azure": "workspace:^" + "@backstage/plugin-scaffolder-backend-module-bitbucket": "workspace:^" + "@backstage/plugin-scaffolder-backend-module-gerrit": "workspace:^" + "@backstage/plugin-scaffolder-backend-module-github": "workspace:^" + "@backstage/plugin-scaffolder-backend-module-gitlab": "workspace:^" "@backstage/plugin-scaffolder-common": "workspace:^" "@backstage/plugin-scaffolder-node": "workspace:^" "@backstage/types": "workspace:^" - "@gitbeaker/core": ^35.6.0 - "@gitbeaker/node": ^35.1.0 - "@octokit/webhooks": ^10.0.0 "@types/command-exists": ^1.2.0 "@types/express": ^4.17.6 "@types/fs-extra": ^9.0.1 "@types/git-url-parse": ^9.0.0 - "@types/libsodium-wrappers": ^0.7.10 "@types/luxon": ^3.0.0 "@types/nunjucks": ^3.1.4 "@types/supertest": ^2.0.8 @@ -8774,15 +8849,12 @@ __metadata: jest-when: ^3.1.0 jsonschema: ^1.2.6 knex: ^3.0.0 - libsodium-wrappers: ^0.7.11 lodash: ^4.17.21 luxon: ^3.0.0 morgan: ^1.10.0 msw: ^1.0.0 node-fetch: ^2.6.7 nunjucks: ^3.2.3 - octokit: ^2.0.0 - octokit-plugin-create-pull-request: ^3.10.0 p-limit: ^3.1.0 p-queue: ^6.6.2 prom-client: ^14.0.1 @@ -8814,6 +8886,7 @@ __metadata: dependencies: "@backstage/backend-common": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" + "@backstage/backend-test-utils": "workspace:^" "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" @@ -8822,7 +8895,9 @@ __metadata: "@backstage/plugin-scaffolder-common": "workspace:^" "@backstage/types": "workspace:^" fs-extra: 10.1.0 + globby: ^11.0.0 jsonschema: ^1.2.6 + p-limit: ^3.1.0 winston: ^3.2.1 zod: ^3.21.4 zod-to-json-schema: ^3.20.4 @@ -11555,7 +11630,7 @@ __metadata: languageName: node linkType: hard -"@gitbeaker/core@npm:^35.6.0, @gitbeaker/core@npm:^35.8.1": +"@gitbeaker/core@npm:^35.6.0, @gitbeaker/core@npm:^35.8.0, @gitbeaker/core@npm:^35.8.1": version: 35.8.1 resolution: "@gitbeaker/core@npm:35.8.1" dependencies: @@ -11569,7 +11644,7 @@ __metadata: languageName: node linkType: hard -"@gitbeaker/node@npm:^35.1.0, @gitbeaker/node@npm:^35.8.0": +"@gitbeaker/node@npm:^35.1.0": version: 35.8.1 resolution: "@gitbeaker/node@npm:35.8.1" dependencies: From 04559e342286e4b4360d054d708c0ec4bc5df76b Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 6 Dec 2023 14:29:03 +0100 Subject: [PATCH 092/275] chore: update API reports Signed-off-by: blam --- .../api-report.md | 28 + .../src/index.ts | 2 +- .../api-report.md | 82 +++ .../src/index.ts | 2 +- .../api-report.md | 43 ++ .../package.json | 4 +- .../src/index.ts | 2 +- .../api-report.md | 365 ++++++++++++ .../githubPullRequest.examples.test.ts | 9 +- .../src/actions/githubPullRequest.test.ts | 9 +- .../src/actions/githubPullRequest.ts | 94 ++- .../src/actions/index.ts | 5 +- .../src/index.ts | 2 +- .../api-report.md | 72 +++ .../src/index.ts | 3 +- plugins/scaffolder-backend/api-report.md | 555 ------------------ plugins/scaffolder-node/api-report.md | 109 ++++ .../actions/{repoHelpers.ts => gitHelpers.ts} | 6 + plugins/scaffolder-node/src/actions/index.ts | 2 +- plugins/scaffolder-node/src/actions/util.ts | 6 + .../src/files/deserializeDirectoryContents.ts | 2 +- .../src/files/serializeDirectoryContents.ts | 3 + plugins/scaffolder-node/src/files/types.ts | 3 + .../scaffolder-react/src/components/types.ts | 1 - 24 files changed, 778 insertions(+), 631 deletions(-) create mode 100644 plugins/scaffolder-backend-module-azure/api-report.md create mode 100644 plugins/scaffolder-backend-module-bitbucket/api-report.md create mode 100644 plugins/scaffolder-backend-module-gerrit/api-report.md create mode 100644 plugins/scaffolder-backend-module-github/api-report.md rename plugins/scaffolder-node/src/actions/{repoHelpers.ts => gitHelpers.ts} (98%) diff --git a/plugins/scaffolder-backend-module-azure/api-report.md b/plugins/scaffolder-backend-module-azure/api-report.md new file mode 100644 index 0000000000..427ed2d1bf --- /dev/null +++ b/plugins/scaffolder-backend-module-azure/api-report.md @@ -0,0 +1,28 @@ +## API Report File for "@backstage/plugin-scaffolder-backend-module-azure" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { Config } from '@backstage/config'; +import { JsonObject } from '@backstage/types'; +import { ScmIntegrationRegistry } from '@backstage/integration'; +import { TemplateAction } from '@backstage/plugin-scaffolder-node'; + +// @public +export function createPublishAzureAction(options: { + integrations: ScmIntegrationRegistry; + config: Config; +}): TemplateAction< + { + repoUrl: string; + description?: string | undefined; + defaultBranch?: string | undefined; + sourcePath?: string | undefined; + token?: string | undefined; + gitCommitMessage?: string | undefined; + gitAuthorName?: string | undefined; + gitAuthorEmail?: string | undefined; + }, + JsonObject +>; +``` diff --git a/plugins/scaffolder-backend-module-azure/src/index.ts b/plugins/scaffolder-backend-module-azure/src/index.ts index d64ca54077..e804f1a504 100644 --- a/plugins/scaffolder-backend-module-azure/src/index.ts +++ b/plugins/scaffolder-backend-module-azure/src/index.ts @@ -15,7 +15,7 @@ */ /** - * The azure module for @backstage/plugin-scaffolder-backend. + * A module for the scaffolder backend that lets you interact with azure * * @packageDocumentation */ diff --git a/plugins/scaffolder-backend-module-bitbucket/api-report.md b/plugins/scaffolder-backend-module-bitbucket/api-report.md new file mode 100644 index 0000000000..8e58c5fe7e --- /dev/null +++ b/plugins/scaffolder-backend-module-bitbucket/api-report.md @@ -0,0 +1,82 @@ +## API Report File for "@backstage/plugin-scaffolder-backend-module-bitbucket" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { Config } from '@backstage/config'; +import { JsonObject } from '@backstage/types'; +import { ScmIntegrationRegistry } from '@backstage/integration'; +import { TemplateAction } from '@backstage/plugin-scaffolder-node'; + +// @public @deprecated +export function createPublishBitbucketAction(options: { + integrations: ScmIntegrationRegistry; + config: Config; +}): TemplateAction< + { + repoUrl: string; + description?: string | undefined; + defaultBranch?: string | undefined; + repoVisibility?: 'private' | 'public' | undefined; + sourcePath?: string | undefined; + enableLFS?: boolean | undefined; + token?: string | undefined; + gitCommitMessage?: string | undefined; + gitAuthorName?: string | undefined; + gitAuthorEmail?: string | undefined; + }, + JsonObject +>; + +// @public +export function createPublishBitbucketCloudAction(options: { + integrations: ScmIntegrationRegistry; + config: Config; +}): TemplateAction< + { + repoUrl: string; + description?: string | undefined; + defaultBranch?: string | undefined; + repoVisibility?: 'private' | 'public' | undefined; + sourcePath?: string | undefined; + token?: string | undefined; + }, + JsonObject +>; + +// @public +export function createPublishBitbucketServerAction(options: { + integrations: ScmIntegrationRegistry; + config: Config; +}): TemplateAction< + { + repoUrl: string; + description?: string | undefined; + defaultBranch?: string | undefined; + repoVisibility?: 'private' | 'public' | undefined; + sourcePath?: string | undefined; + enableLFS?: boolean | undefined; + token?: string | undefined; + gitCommitMessage?: string | undefined; + gitAuthorName?: string | undefined; + gitAuthorEmail?: string | undefined; + }, + JsonObject +>; + +// @public +export function createPublishBitbucketServerPullRequestAction(options: { + integrations: ScmIntegrationRegistry; + config: Config; +}): TemplateAction< + { + repoUrl: string; + title: string; + description?: string | undefined; + targetBranch?: string | undefined; + sourceBranch: string; + token?: string | undefined; + }, + JsonObject +>; +``` diff --git a/plugins/scaffolder-backend-module-bitbucket/src/index.ts b/plugins/scaffolder-backend-module-bitbucket/src/index.ts index 6448b82c8b..38d973efb8 100644 --- a/plugins/scaffolder-backend-module-bitbucket/src/index.ts +++ b/plugins/scaffolder-backend-module-bitbucket/src/index.ts @@ -15,7 +15,7 @@ */ /** - * The bitbucket module for @backstage/plugin-scaffolder-backend. + * A module for the scaffolder backend that lets you interact with bitbucket * * @packageDocumentation */ diff --git a/plugins/scaffolder-backend-module-gerrit/api-report.md b/plugins/scaffolder-backend-module-gerrit/api-report.md new file mode 100644 index 0000000000..309de08574 --- /dev/null +++ b/plugins/scaffolder-backend-module-gerrit/api-report.md @@ -0,0 +1,43 @@ +## API Report File for "@backstage/plugin-scaffolder-backend-module-gerrit" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { Config } from '@backstage/config'; +import { JsonObject } from '@backstage/types'; +import { ScmIntegrationRegistry } from '@backstage/integration'; +import { TemplateAction } from '@backstage/plugin-scaffolder-node'; + +// @public +export function createPublishGerritAction(options: { + integrations: ScmIntegrationRegistry; + config: Config; +}): TemplateAction< + { + repoUrl: string; + description: string; + defaultBranch?: string | undefined; + gitCommitMessage?: string | undefined; + gitAuthorName?: string | undefined; + gitAuthorEmail?: string | undefined; + sourcePath?: string | undefined; + }, + JsonObject +>; + +// @public +export function createPublishGerritReviewAction(options: { + integrations: ScmIntegrationRegistry; + config: Config; +}): TemplateAction< + { + repoUrl: string; + branch?: string | undefined; + sourcePath?: string | undefined; + gitCommitMessage?: string | undefined; + gitAuthorName?: string | undefined; + gitAuthorEmail?: string | undefined; + }, + JsonObject +>; +``` diff --git a/plugins/scaffolder-backend-module-gerrit/package.json b/plugins/scaffolder-backend-module-gerrit/package.json index f3797accb3..9502d9967d 100644 --- a/plugins/scaffolder-backend-module-gerrit/package.json +++ b/plugins/scaffolder-backend-module-gerrit/package.json @@ -23,10 +23,10 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/plugin-scaffolder-node": "workspace:^", + "@backstage/config": "workspace:^", "@backstage/errors": "workspace:^", "@backstage/integration": "workspace:^", - "@backstage/config": "workspace:^", + "@backstage/plugin-scaffolder-node": "workspace:^", "node-fetch": "^2.6.7", "yaml": "^2.0.0" }, diff --git a/plugins/scaffolder-backend-module-gerrit/src/index.ts b/plugins/scaffolder-backend-module-gerrit/src/index.ts index 21fdd116e7..b00c307fa5 100644 --- a/plugins/scaffolder-backend-module-gerrit/src/index.ts +++ b/plugins/scaffolder-backend-module-gerrit/src/index.ts @@ -15,7 +15,7 @@ */ /** - * The gerrit module for @backstage/plugin-scaffolder-backend. + * A module for the scaffolder backend that lets you interact with gerrit * * @packageDocumentation */ diff --git a/plugins/scaffolder-backend-module-github/api-report.md b/plugins/scaffolder-backend-module-github/api-report.md new file mode 100644 index 0000000000..bb3ec4e7c4 --- /dev/null +++ b/plugins/scaffolder-backend-module-github/api-report.md @@ -0,0 +1,365 @@ +## API Report File for "@backstage/plugin-scaffolder-backend-module-github" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { Config } from '@backstage/config'; +import { createPullRequest } from 'octokit-plugin-create-pull-request'; +import { GithubCredentialsProvider } from '@backstage/integration'; +import { JsonObject } from '@backstage/types'; +import { Octokit } from 'octokit'; +import { ScmIntegrationRegistry } from '@backstage/integration'; +import { ScmIntegrations } from '@backstage/integration'; +import { TemplateAction } from '@backstage/plugin-scaffolder-node'; + +// @public +export function createGithubActionsDispatchAction(options: { + integrations: ScmIntegrations; + githubCredentialsProvider?: GithubCredentialsProvider; +}): TemplateAction< + { + repoUrl: string; + workflowId: string; + branchOrTagName: string; + workflowInputs?: + | { + [key: string]: string; + } + | undefined; + token?: string | undefined; + }, + JsonObject +>; + +// @public +export function createGithubDeployKeyAction(options: { + integrations: ScmIntegrationRegistry; +}): TemplateAction< + { + repoUrl: string; + publicKey: string; + privateKey: string; + deployKeyName: string; + privateKeySecretName?: string | undefined; + token?: string | undefined; + }, + JsonObject +>; + +// @public +export function createGithubEnvironmentAction(options: { + integrations: ScmIntegrationRegistry; +}): TemplateAction< + { + repoUrl: string; + name: string; + deploymentBranchPolicy?: + | { + protected_branches: boolean; + custom_branch_policies: boolean; + } + | undefined; + customBranchPolicyNames?: string[] | undefined; + environmentVariables?: + | { + [key: string]: string; + } + | undefined; + secrets?: + | { + [key: string]: string; + } + | undefined; + token?: string | undefined; + }, + JsonObject +>; + +// @public +export function createGithubIssuesLabelAction(options: { + integrations: ScmIntegrationRegistry; + githubCredentialsProvider?: GithubCredentialsProvider; +}): TemplateAction< + { + repoUrl: string; + number: number; + labels: string[]; + token?: string | undefined; + }, + JsonObject +>; + +// @public +export interface CreateGithubPullRequestActionOptions { + clientFactory?: (input: { + integrations: ScmIntegrationRegistry; + githubCredentialsProvider?: GithubCredentialsProvider; + host: string; + owner: string; + repo: string; + token?: string; + }) => Promise< + Octokit & { + createPullRequest(options: createPullRequest.Options): Promise<{ + data: { + html_url: string; + number: number; + base: { + ref: string; + }; + }; + } | null>; + } + >; + githubCredentialsProvider?: GithubCredentialsProvider; + integrations: ScmIntegrationRegistry; +} + +// @public +export function createGithubRepoCreateAction(options: { + integrations: ScmIntegrationRegistry; + githubCredentialsProvider?: GithubCredentialsProvider; +}): TemplateAction< + { + repoUrl: string; + description?: string | undefined; + homepage?: string | undefined; + access?: string | undefined; + deleteBranchOnMerge?: boolean | undefined; + gitAuthorName?: string | undefined; + gitAuthorEmail?: string | undefined; + allowRebaseMerge?: boolean | undefined; + allowSquashMerge?: boolean | undefined; + squashMergeCommitTitle?: 'PR_TITLE' | 'COMMIT_OR_PR_TITLE' | undefined; + squashMergeCommitMessage?: + | 'PR_BODY' + | 'COMMIT_MESSAGES' + | 'BLANK' + | undefined; + allowMergeCommit?: boolean | undefined; + allowAutoMerge?: boolean | undefined; + requireCodeOwnerReviews?: boolean | undefined; + bypassPullRequestAllowances?: + | { + users?: string[] | undefined; + teams?: string[] | undefined; + apps?: string[] | undefined; + } + | undefined; + requiredApprovingReviewCount?: number | undefined; + restrictions?: + | { + users: string[]; + teams: string[]; + apps?: string[] | undefined; + } + | undefined; + requiredStatusCheckContexts?: string[] | undefined; + requireBranchesToBeUpToDate?: boolean | undefined; + requiredConversationResolution?: boolean | undefined; + repoVisibility?: 'internal' | 'private' | 'public' | undefined; + collaborators?: + | ( + | { + user: string; + access: string; + } + | { + team: string; + access: string; + } + | { + username: string; + access: 'pull' | 'push' | 'admin' | 'maintain' | 'triage'; + } + )[] + | undefined; + hasProjects?: boolean | undefined; + hasWiki?: boolean | undefined; + hasIssues?: boolean | undefined; + token?: string | undefined; + topics?: string[] | undefined; + repoVariables?: + | { + [key: string]: string; + } + | undefined; + secrets?: + | { + [key: string]: string; + } + | undefined; + requireCommitSigning?: boolean | undefined; + }, + JsonObject +>; + +// @public +export function createGithubRepoPushAction(options: { + integrations: ScmIntegrationRegistry; + config: Config; + githubCredentialsProvider?: GithubCredentialsProvider; +}): TemplateAction< + { + repoUrl: string; + description?: string | undefined; + defaultBranch?: string | undefined; + protectDefaultBranch?: boolean | undefined; + protectEnforceAdmins?: boolean | undefined; + gitCommitMessage?: string | undefined; + gitAuthorName?: string | undefined; + gitAuthorEmail?: string | undefined; + requireCodeOwnerReviews?: boolean | undefined; + dismissStaleReviews?: boolean | undefined; + bypassPullRequestAllowances?: + | { + users?: string[]; + teams?: string[]; + apps?: string[]; + } + | undefined; + requiredApprovingReviewCount?: number | undefined; + restrictions?: + | { + users: string[]; + teams: string[]; + apps?: string[]; + } + | undefined; + requiredStatusCheckContexts?: string[] | undefined; + requireBranchesToBeUpToDate?: boolean | undefined; + requiredConversationResolution?: boolean | undefined; + sourcePath?: string | undefined; + token?: string | undefined; + requiredCommitSigning?: boolean | undefined; + }, + JsonObject +>; + +// @public +export function createGithubWebhookAction(options: { + integrations: ScmIntegrationRegistry; + defaultWebhookSecret?: string; + githubCredentialsProvider?: GithubCredentialsProvider; +}): TemplateAction< + { + repoUrl: string; + webhookUrl: string; + webhookSecret?: string | undefined; + events?: string[] | undefined; + active?: boolean | undefined; + contentType?: 'form' | 'json' | undefined; + insecureSsl?: boolean | undefined; + token?: string | undefined; + }, + JsonObject +>; + +// @public +export function createPublishGithubAction(options: { + integrations: ScmIntegrationRegistry; + config: Config; + githubCredentialsProvider?: GithubCredentialsProvider; +}): TemplateAction< + { + repoUrl: string; + description?: string | undefined; + homepage?: string | undefined; + access?: string | undefined; + defaultBranch?: string | undefined; + protectDefaultBranch?: boolean | undefined; + protectEnforceAdmins?: boolean | undefined; + deleteBranchOnMerge?: boolean | undefined; + gitCommitMessage?: string | undefined; + gitAuthorName?: string | undefined; + gitAuthorEmail?: string | undefined; + allowRebaseMerge?: boolean | undefined; + allowSquashMerge?: boolean | undefined; + squashMergeCommitTitle?: 'PR_TITLE' | 'COMMIT_OR_PR_TITLE' | undefined; + squashMergeCommitMessage?: + | 'PR_BODY' + | 'COMMIT_MESSAGES' + | 'BLANK' + | undefined; + allowMergeCommit?: boolean | undefined; + allowAutoMerge?: boolean | undefined; + sourcePath?: string | undefined; + bypassPullRequestAllowances?: + | { + users?: string[]; + teams?: string[]; + apps?: string[]; + } + | undefined; + requiredApprovingReviewCount?: number | undefined; + restrictions?: + | { + users: string[]; + teams: string[]; + apps?: string[]; + } + | undefined; + requireCodeOwnerReviews?: boolean | undefined; + dismissStaleReviews?: boolean | undefined; + requiredStatusCheckContexts?: string[] | undefined; + requireBranchesToBeUpToDate?: boolean | undefined; + requiredConversationResolution?: boolean | undefined; + repoVisibility?: 'internal' | 'private' | 'public' | undefined; + collaborators?: + | ( + | { + user: string; + access: string; + } + | { + team: string; + access: string; + } + | { + username: string; + access: 'pull' | 'push' | 'admin' | 'maintain' | 'triage'; + } + )[] + | undefined; + hasProjects?: boolean | undefined; + hasWiki?: boolean | undefined; + hasIssues?: boolean | undefined; + token?: string | undefined; + topics?: string[] | undefined; + repoVariables?: + | { + [key: string]: string; + } + | undefined; + secrets?: + | { + [key: string]: string; + } + | undefined; + requiredCommitSigning?: boolean | undefined; + }, + JsonObject +>; + +// @public +export const createPublishGithubPullRequestAction: ( + options: CreateGithubPullRequestActionOptions, +) => TemplateAction< + { + title: string; + branchName: string; + targetBranchName?: string | undefined; + description: string; + repoUrl: string; + draft?: boolean | undefined; + targetPath?: string | undefined; + sourcePath?: string | undefined; + token?: string | undefined; + reviewers?: string[] | undefined; + teamReviewers?: string[] | undefined; + commitMessage?: string | undefined; + update?: boolean | undefined; + }, + JsonObject +>; +``` diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubPullRequest.examples.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubPullRequest.examples.test.ts index 3f13f2ab67..7e5d107026 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubPullRequest.examples.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubPullRequest.examples.test.ts @@ -23,10 +23,7 @@ import { ScmIntegrations, } from '@backstage/integration'; import { PassThrough } from 'stream'; -import { - OctokitWithPullRequestPluginClient, - createPublishGithubPullRequestAction, -} from './githubPullRequest'; +import { createPublishGithubPullRequestAction } from './githubPullRequest'; import yaml from 'yaml'; import { examples } from './githubPullRequest.examples'; import { createMockDirectory } from '@backstage/backend-test-utils'; @@ -103,9 +100,7 @@ describe('publish:github:pull-request examples', () => { }, }; - const clientFactory = jest.fn( - async () => fakeClient as unknown as OctokitWithPullRequestPluginClient, - ); + const clientFactory = jest.fn(async () => fakeClient as any); mockDir.setContent({ [workspacePath]: { 'file.txt': 'Hello there!' }, diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubPullRequest.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubPullRequest.test.ts index a1f3712a9d..23ac4bda45 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubPullRequest.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubPullRequest.test.ts @@ -26,10 +26,7 @@ import { } from '@backstage/plugin-scaffolder-node'; import fs from 'fs-extra'; import { Writable } from 'stream'; -import { - createPublishGithubPullRequestAction, - OctokitWithPullRequestPluginClient, -} from './githubPullRequest'; +import { createPublishGithubPullRequestAction } from './githubPullRequest'; import { createMockDirectory } from '@backstage/backend-test-utils'; // Make sure root logger is initialized ahead of FS mock @@ -78,9 +75,7 @@ describe('createPublishGithubPullRequestAction', () => { }, }, }; - const clientFactory = jest.fn( - async () => fakeClient as unknown as OctokitWithPullRequestPluginClient, - ); + const clientFactory = jest.fn(async () => fakeClient as any); const githubCredentialsProvider: GithubCredentialsProvider = { getCredentials: jest.fn(), }; diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubPullRequest.ts b/plugins/scaffolder-backend-module-github/src/actions/githubPullRequest.ts index 00e584226f..0763d4a474 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubPullRequest.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubPullRequest.ts @@ -37,57 +37,32 @@ export type Encoding = 'utf-8' | 'base64'; class GithubResponseError extends CustomErrorBase {} -/** @public */ -export type OctokitWithPullRequestPluginClient = Octokit & { - createPullRequest(options: createPullRequest.Options): Promise<{ - data: { - html_url: string; - number: number; - base: { - ref: string; - }; - }; - } | null>; -}; - -/** - * The options passed to the client factory function. - * @public - */ -export type CreateGithubPullRequestClientFactoryInput = { - integrations: ScmIntegrationRegistry; - githubCredentialsProvider?: GithubCredentialsProvider; - host: string; - owner: string; - repo: string; - token?: string; -}; - -export const defaultClientFactory = async ({ - integrations, - githubCredentialsProvider, - owner, - repo, - host = 'github.com', - token: providedToken, -}: CreateGithubPullRequestClientFactoryInput): Promise => { - const [encodedHost, encodedOwner, encodedRepo] = [host, owner, repo].map( - encodeURIComponent, - ); - - const octokitOptions = await getOctokitOptions({ +export const defaultClientFactory: CreateGithubPullRequestActionOptions['clientFactory'] = + async ({ integrations, - credentialsProvider: githubCredentialsProvider, - repoUrl: `${encodedHost}?owner=${encodedOwner}&repo=${encodedRepo}`, + githubCredentialsProvider, + owner, + repo, + host = 'github.com', token: providedToken, - }); + }) => { + const [encodedHost, encodedOwner, encodedRepo] = [host, owner, repo].map( + encodeURIComponent, + ); - const OctokitPR = Octokit.plugin(createPullRequest); - return new OctokitPR({ - ...octokitOptions, - ...{ throttle: { enabled: false } }, - }); -}; + const octokitOptions = await getOctokitOptions({ + integrations, + credentialsProvider: githubCredentialsProvider, + repoUrl: `${encodedHost}?owner=${encodedOwner}&repo=${encodedRepo}`, + token: providedToken, + }); + + const OctokitPR = Octokit.plugin(createPullRequest); + return new OctokitPR({ + ...octokitOptions, + ...{ throttle: { enabled: false } }, + }); + }; /** * The options passed to {@link createPublishGithubPullRequestAction} method @@ -105,9 +80,26 @@ export interface CreateGithubPullRequestActionOptions { /** * A method to return the Octokit client with the Pull Request Plugin. */ - clientFactory?: ( - input: CreateGithubPullRequestClientFactoryInput, - ) => Promise; + clientFactory?: (input: { + integrations: ScmIntegrationRegistry; + githubCredentialsProvider?: GithubCredentialsProvider; + host: string; + owner: string; + repo: string; + token?: string; + }) => Promise< + Octokit & { + createPullRequest(options: createPullRequest.Options): Promise<{ + data: { + html_url: string; + number: number; + base: { + ref: string; + }; + }; + } | null>; + } + >; } type GithubPullRequest = { diff --git a/plugins/scaffolder-backend-module-github/src/actions/index.ts b/plugins/scaffolder-backend-module-github/src/actions/index.ts index 9c3927f31d..ebcda41d93 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/index.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/index.ts @@ -22,5 +22,8 @@ export { createGithubWebhookAction } from './githubWebhook'; export { createGithubDeployKeyAction } from './githubDeployKey'; export { createGithubEnvironmentAction } from './githubEnvironment'; -export { createPublishGithubPullRequestAction } from './githubPullRequest'; +export { + createPublishGithubPullRequestAction, + type CreateGithubPullRequestActionOptions, +} from './githubPullRequest'; export { createPublishGithubAction } from './github'; diff --git a/plugins/scaffolder-backend-module-github/src/index.ts b/plugins/scaffolder-backend-module-github/src/index.ts index b4d8dbcb6d..948a79d957 100644 --- a/plugins/scaffolder-backend-module-github/src/index.ts +++ b/plugins/scaffolder-backend-module-github/src/index.ts @@ -15,7 +15,7 @@ */ /** - * The github module for @backstage/plugin-scaffolder-backend. + * A module for the scaffolder backend that lets you interact with github * * @packageDocumentation */ diff --git a/plugins/scaffolder-backend-module-gitlab/api-report.md b/plugins/scaffolder-backend-module-gitlab/api-report.md index eccada5d51..debc31412a 100644 --- a/plugins/scaffolder-backend-module-gitlab/api-report.md +++ b/plugins/scaffolder-backend-module-gitlab/api-report.md @@ -3,6 +3,7 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +import { Config } from '@backstage/config'; import { JsonObject } from '@backstage/types'; import { ScmIntegrationRegistry } from '@backstage/integration'; import { TemplateAction } from '@backstage/plugin-scaffolder-node'; @@ -74,4 +75,75 @@ export const createGitlabProjectVariableAction: (options: { }, JsonObject >; + +// @public +export function createPublishGitlabAction(options: { + integrations: ScmIntegrationRegistry; + config: Config; +}): TemplateAction< + { + repoUrl: string; + defaultBranch?: string | undefined; + repoVisibility?: 'internal' | 'private' | 'public' | undefined; + sourcePath?: string | undefined; + token?: string | undefined; + gitCommitMessage?: string | undefined; + gitAuthorName?: string | undefined; + gitAuthorEmail?: string | undefined; + setUserAsOwner?: boolean | undefined; + topics?: string[] | undefined; + settings?: + | { + path?: string | undefined; + auto_devops_enabled?: boolean | undefined; + ci_config_path?: string | undefined; + description?: string | undefined; + topics?: string[] | undefined; + visibility?: 'internal' | 'private' | 'public' | undefined; + } + | undefined; + branches?: + | { + name: string; + protect?: boolean | undefined; + create?: boolean | undefined; + ref?: string | undefined; + }[] + | undefined; + projectVariables?: + | { + key: string; + value: string; + description?: string | undefined; + variable_type?: string | undefined; + protected?: boolean | undefined; + masked?: boolean | undefined; + raw?: boolean | undefined; + environment_scope?: string | undefined; + }[] + | undefined; + }, + JsonObject +>; + +// @public +export const createPublishGitlabMergeRequestAction: (options: { + integrations: ScmIntegrationRegistry; +}) => TemplateAction< + { + repoUrl: string; + title: string; + description: string; + branchName: string; + targetBranchName?: string | undefined; + sourcePath?: string | undefined; + targetPath?: string | undefined; + token?: string | undefined; + commitAction?: 'update' | 'delete' | 'create' | undefined; + projectid?: string | undefined; + removeSourceBranch?: boolean | undefined; + assignee?: string | undefined; + }, + JsonObject +>; ``` diff --git a/plugins/scaffolder-backend-module-gitlab/src/index.ts b/plugins/scaffolder-backend-module-gitlab/src/index.ts index 844f753344..11d4247569 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/index.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/index.ts @@ -1,5 +1,5 @@ /* - * Copyright 2021 The Backstage Authors + * Copyright 2023 The Backstage Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,4 +19,5 @@ * * @packageDocumentation */ + export * from './actions'; diff --git a/plugins/scaffolder-backend/api-report.md b/plugins/scaffolder-backend/api-report.md index b92b883767..72af83aa6b 100644 --- a/plugins/scaffolder-backend/api-report.md +++ b/plugins/scaffolder-backend/api-report.md @@ -6,19 +6,16 @@ import { ActionContext as ActionContext_2 } from '@backstage/plugin-scaffolder-node'; import { CatalogApi } from '@backstage/catalog-client'; import { Config } from '@backstage/config'; -import { createPullRequest } from 'octokit-plugin-create-pull-request'; import { Duration } from 'luxon'; import { executeShellCommand as executeShellCommand_2 } from '@backstage/plugin-scaffolder-node'; import { ExecuteShellCommandOptions } from '@backstage/plugin-scaffolder-node'; import express from 'express'; import { fetchContents as fetchContents_2 } from '@backstage/plugin-scaffolder-node'; -import { GithubCredentialsProvider } from '@backstage/integration'; import { HumanDuration } from '@backstage/types'; import { IdentityApi } from '@backstage/plugin-auth-node'; import { JsonObject } from '@backstage/types'; import { Knex } from 'knex'; import { Logger } from 'winston'; -import { Octokit } from 'octokit'; import { PermissionEvaluator } from '@backstage/plugin-permission-common'; import { PermissionRule } from '@backstage/plugin-permission-node'; import { PermissionRuleParams } from '@backstage/plugin-permission-common'; @@ -28,7 +25,6 @@ import { RESOURCE_TYPE_SCAFFOLDER_ACTION } from '@backstage/plugin-scaffolder-co import { RESOURCE_TYPE_SCAFFOLDER_TEMPLATE } from '@backstage/plugin-scaffolder-common/alpha'; import { ScaffolderEntitiesProcessor as ScaffolderEntitiesProcessor_2 } from '@backstage/plugin-catalog-backend-module-scaffolder-entity-model'; import { Schema } from 'jsonschema'; -import { ScmIntegrationRegistry } from '@backstage/integration'; import { ScmIntegrations } from '@backstage/integration'; import { SerializedTask as SerializedTask_2 } from '@backstage/plugin-scaffolder-node'; import { SerializedTaskEvent as SerializedTaskEvent_2 } from '@backstage/plugin-scaffolder-node'; @@ -197,544 +193,6 @@ export const createFilesystemRenameAction: () => TemplateAction_2< JsonObject >; -// @public -export function createGithubActionsDispatchAction(options: { - integrations: ScmIntegrations; - githubCredentialsProvider?: GithubCredentialsProvider; -}): TemplateAction_2< - { - repoUrl: string; - workflowId: string; - branchOrTagName: string; - workflowInputs?: - | { - [key: string]: string; - } - | undefined; - token?: string | undefined; - }, - JsonObject ->; - -// @public -export function createGithubDeployKeyAction(options: { - integrations: ScmIntegrationRegistry; -}): TemplateAction_2< - { - repoUrl: string; - publicKey: string; - privateKey: string; - deployKeyName: string; - privateKeySecretName?: string | undefined; - token?: string | undefined; - }, - JsonObject ->; - -// @public -export function createGithubEnvironmentAction(options: { - integrations: ScmIntegrationRegistry; -}): TemplateAction_2< - { - repoUrl: string; - name: string; - deploymentBranchPolicy?: - | { - protected_branches: boolean; - custom_branch_policies: boolean; - } - | undefined; - customBranchPolicyNames?: string[] | undefined; - environmentVariables?: - | { - [key: string]: string; - } - | undefined; - secrets?: - | { - [key: string]: string; - } - | undefined; - token?: string | undefined; - }, - JsonObject ->; - -// @public -export function createGithubIssuesLabelAction(options: { - integrations: ScmIntegrationRegistry; - githubCredentialsProvider?: GithubCredentialsProvider; -}): TemplateAction_2< - { - repoUrl: string; - number: number; - labels: string[]; - token?: string | undefined; - }, - JsonObject ->; - -// @public -export interface CreateGithubPullRequestActionOptions { - clientFactory?: ( - input: CreateGithubPullRequestClientFactoryInput, - ) => Promise; - githubCredentialsProvider?: GithubCredentialsProvider; - integrations: ScmIntegrationRegistry; -} - -// @public -export type CreateGithubPullRequestClientFactoryInput = { - integrations: ScmIntegrationRegistry; - githubCredentialsProvider?: GithubCredentialsProvider; - host: string; - owner: string; - repo: string; - token?: string; -}; - -// @public -export function createGithubRepoCreateAction(options: { - integrations: ScmIntegrationRegistry; - githubCredentialsProvider?: GithubCredentialsProvider; -}): TemplateAction_2< - { - repoUrl: string; - description?: string | undefined; - homepage?: string | undefined; - access?: string | undefined; - deleteBranchOnMerge?: boolean | undefined; - gitAuthorName?: string | undefined; - gitAuthorEmail?: string | undefined; - allowRebaseMerge?: boolean | undefined; - allowSquashMerge?: boolean | undefined; - squashMergeCommitTitle?: 'PR_TITLE' | 'COMMIT_OR_PR_TITLE' | undefined; - squashMergeCommitMessage?: - | 'PR_BODY' - | 'COMMIT_MESSAGES' - | 'BLANK' - | undefined; - allowMergeCommit?: boolean | undefined; - allowAutoMerge?: boolean | undefined; - requireCodeOwnerReviews?: boolean | undefined; - bypassPullRequestAllowances?: - | { - users?: string[] | undefined; - teams?: string[] | undefined; - apps?: string[] | undefined; - } - | undefined; - requiredApprovingReviewCount?: number | undefined; - restrictions?: - | { - users: string[]; - teams: string[]; - apps?: string[] | undefined; - } - | undefined; - requiredStatusCheckContexts?: string[] | undefined; - requireBranchesToBeUpToDate?: boolean | undefined; - requiredConversationResolution?: boolean | undefined; - repoVisibility?: 'internal' | 'private' | 'public' | undefined; - collaborators?: - | ( - | { - user: string; - access: string; - } - | { - team: string; - access: string; - } - | { - username: string; - access: 'pull' | 'push' | 'admin' | 'maintain' | 'triage'; - } - )[] - | undefined; - hasProjects?: boolean | undefined; - hasWiki?: boolean | undefined; - hasIssues?: boolean | undefined; - token?: string | undefined; - topics?: string[] | undefined; - repoVariables?: - | { - [key: string]: string; - } - | undefined; - secrets?: - | { - [key: string]: string; - } - | undefined; - requireCommitSigning?: boolean | undefined; - }, - JsonObject ->; - -// @public -export function createGithubRepoPushAction(options: { - integrations: ScmIntegrationRegistry; - config: Config; - githubCredentialsProvider?: GithubCredentialsProvider; -}): TemplateAction_2< - { - repoUrl: string; - description?: string | undefined; - defaultBranch?: string | undefined; - protectDefaultBranch?: boolean | undefined; - protectEnforceAdmins?: boolean | undefined; - gitCommitMessage?: string | undefined; - gitAuthorName?: string | undefined; - gitAuthorEmail?: string | undefined; - requireCodeOwnerReviews?: boolean | undefined; - dismissStaleReviews?: boolean | undefined; - bypassPullRequestAllowances?: - | { - users?: string[]; - teams?: string[]; - apps?: string[]; - } - | undefined; - requiredApprovingReviewCount?: number | undefined; - restrictions?: - | { - users: string[]; - teams: string[]; - apps?: string[]; - } - | undefined; - requiredStatusCheckContexts?: string[] | undefined; - requireBranchesToBeUpToDate?: boolean | undefined; - requiredConversationResolution?: boolean | undefined; - sourcePath?: string | undefined; - token?: string | undefined; - requiredCommitSigning?: boolean | undefined; - }, - JsonObject ->; - -// @public -export function createGithubWebhookAction(options: { - integrations: ScmIntegrationRegistry; - defaultWebhookSecret?: string; - githubCredentialsProvider?: GithubCredentialsProvider; -}): TemplateAction_2< - { - repoUrl: string; - webhookUrl: string; - webhookSecret?: string | undefined; - events?: string[] | undefined; - active?: boolean | undefined; - contentType?: 'form' | 'json' | undefined; - insecureSsl?: boolean | undefined; - token?: string | undefined; - }, - JsonObject ->; - -// @public -export function createPublishAzureAction(options: { - integrations: ScmIntegrationRegistry; - config: Config; -}): TemplateAction_2< - { - repoUrl: string; - description?: string | undefined; - defaultBranch?: string | undefined; - sourcePath?: string | undefined; - token?: string | undefined; - gitCommitMessage?: string | undefined; - gitAuthorName?: string | undefined; - gitAuthorEmail?: string | undefined; - }, - JsonObject ->; - -// @public @deprecated -export function createPublishBitbucketAction(options: { - integrations: ScmIntegrationRegistry; - config: Config; -}): TemplateAction_2< - { - repoUrl: string; - description?: string | undefined; - defaultBranch?: string | undefined; - repoVisibility?: 'private' | 'public' | undefined; - sourcePath?: string | undefined; - enableLFS?: boolean | undefined; - token?: string | undefined; - gitCommitMessage?: string | undefined; - gitAuthorName?: string | undefined; - gitAuthorEmail?: string | undefined; - }, - JsonObject ->; - -// @public -export function createPublishBitbucketCloudAction(options: { - integrations: ScmIntegrationRegistry; - config: Config; -}): TemplateAction_2< - { - repoUrl: string; - description?: string | undefined; - defaultBranch?: string | undefined; - repoVisibility?: 'private' | 'public' | undefined; - sourcePath?: string | undefined; - token?: string | undefined; - }, - JsonObject ->; - -// @public -export function createPublishBitbucketServerAction(options: { - integrations: ScmIntegrationRegistry; - config: Config; -}): TemplateAction_2< - { - repoUrl: string; - description?: string | undefined; - defaultBranch?: string | undefined; - repoVisibility?: 'private' | 'public' | undefined; - sourcePath?: string | undefined; - enableLFS?: boolean | undefined; - token?: string | undefined; - gitCommitMessage?: string | undefined; - gitAuthorName?: string | undefined; - gitAuthorEmail?: string | undefined; - }, - JsonObject ->; - -// @public -export function createPublishBitbucketServerPullRequestAction(options: { - integrations: ScmIntegrationRegistry; - config: Config; -}): TemplateAction_2< - { - repoUrl: string; - title: string; - description?: string | undefined; - targetBranch?: string | undefined; - sourceBranch: string; - token?: string | undefined; - }, - JsonObject ->; - -// @public -export function createPublishGerritAction(options: { - integrations: ScmIntegrationRegistry; - config: Config; -}): TemplateAction_2< - { - repoUrl: string; - description: string; - defaultBranch?: string | undefined; - gitCommitMessage?: string | undefined; - gitAuthorName?: string | undefined; - gitAuthorEmail?: string | undefined; - sourcePath?: string | undefined; - }, - JsonObject ->; - -// @public -export function createPublishGerritReviewAction(options: { - integrations: ScmIntegrationRegistry; - config: Config; -}): TemplateAction_2< - { - repoUrl: string; - branch?: string | undefined; - sourcePath?: string | undefined; - gitCommitMessage?: string | undefined; - gitAuthorName?: string | undefined; - gitAuthorEmail?: string | undefined; - }, - JsonObject ->; - -// @public -export function createPublishGithubAction(options: { - integrations: ScmIntegrationRegistry; - config: Config; - githubCredentialsProvider?: GithubCredentialsProvider; -}): TemplateAction_2< - { - repoUrl: string; - description?: string | undefined; - homepage?: string | undefined; - access?: string | undefined; - defaultBranch?: string | undefined; - protectDefaultBranch?: boolean | undefined; - protectEnforceAdmins?: boolean | undefined; - deleteBranchOnMerge?: boolean | undefined; - gitCommitMessage?: string | undefined; - gitAuthorName?: string | undefined; - gitAuthorEmail?: string | undefined; - allowRebaseMerge?: boolean | undefined; - allowSquashMerge?: boolean | undefined; - squashMergeCommitTitle?: 'PR_TITLE' | 'COMMIT_OR_PR_TITLE' | undefined; - squashMergeCommitMessage?: - | 'PR_BODY' - | 'COMMIT_MESSAGES' - | 'BLANK' - | undefined; - allowMergeCommit?: boolean | undefined; - allowAutoMerge?: boolean | undefined; - sourcePath?: string | undefined; - bypassPullRequestAllowances?: - | { - users?: string[]; - teams?: string[]; - apps?: string[]; - } - | undefined; - requiredApprovingReviewCount?: number | undefined; - restrictions?: - | { - users: string[]; - teams: string[]; - apps?: string[]; - } - | undefined; - requireCodeOwnerReviews?: boolean | undefined; - dismissStaleReviews?: boolean | undefined; - requiredStatusCheckContexts?: string[] | undefined; - requireBranchesToBeUpToDate?: boolean | undefined; - requiredConversationResolution?: boolean | undefined; - repoVisibility?: 'internal' | 'private' | 'public' | undefined; - collaborators?: - | ( - | { - user: string; - access: string; - } - | { - team: string; - access: string; - } - | { - username: string; - access: 'pull' | 'push' | 'admin' | 'maintain' | 'triage'; - } - )[] - | undefined; - hasProjects?: boolean | undefined; - hasWiki?: boolean | undefined; - hasIssues?: boolean | undefined; - token?: string | undefined; - topics?: string[] | undefined; - repoVariables?: - | { - [key: string]: string; - } - | undefined; - secrets?: - | { - [key: string]: string; - } - | undefined; - requiredCommitSigning?: boolean | undefined; - }, - JsonObject ->; - -// @public -export const createPublishGithubPullRequestAction: ( - options: CreateGithubPullRequestActionOptions, -) => TemplateAction_2< - { - title: string; - branchName: string; - targetBranchName?: string | undefined; - description: string; - repoUrl: string; - draft?: boolean | undefined; - targetPath?: string | undefined; - sourcePath?: string | undefined; - token?: string | undefined; - reviewers?: string[] | undefined; - teamReviewers?: string[] | undefined; - commitMessage?: string | undefined; - update?: boolean | undefined; - }, - JsonObject ->; - -// @public -export function createPublishGitlabAction(options: { - integrations: ScmIntegrationRegistry; - config: Config; -}): TemplateAction_2< - { - repoUrl: string; - defaultBranch?: string | undefined; - repoVisibility?: 'internal' | 'private' | 'public' | undefined; - sourcePath?: string | undefined; - token?: string | undefined; - gitCommitMessage?: string | undefined; - gitAuthorName?: string | undefined; - gitAuthorEmail?: string | undefined; - setUserAsOwner?: boolean | undefined; - topics?: string[] | undefined; - settings?: - | { - path?: string | undefined; - auto_devops_enabled?: boolean | undefined; - ci_config_path?: string | undefined; - description?: string | undefined; - topics?: string[] | undefined; - visibility?: 'internal' | 'private' | 'public' | undefined; - } - | undefined; - branches?: - | { - name: string; - protect?: boolean | undefined; - create?: boolean | undefined; - ref?: string | undefined; - }[] - | undefined; - projectVariables?: - | { - key: string; - value: string; - description?: string | undefined; - variable_type?: string | undefined; - protected?: boolean | undefined; - masked?: boolean | undefined; - raw?: boolean | undefined; - environment_scope?: string | undefined; - }[] - | undefined; - }, - JsonObject ->; - -// @public -export const createPublishGitlabMergeRequestAction: (options: { - integrations: ScmIntegrationRegistry; -}) => TemplateAction_2< - { - repoUrl: string; - title: string; - description: string; - branchName: string; - targetBranchName?: string | undefined; - sourcePath?: string | undefined; - targetPath?: string | undefined; - token?: string | undefined; - commitAction?: 'update' | 'delete' | 'create' | undefined; - projectid?: string | undefined; - removeSourceBranch?: boolean | undefined; - assignee?: string | undefined; - }, - JsonObject ->; - // @public export function createRouter(options: RouterOptions): Promise; @@ -858,19 +316,6 @@ export const executeShellCommand: typeof executeShellCommand_2; // @public @deprecated export const fetchContents: typeof fetchContents_2; -// @public (undocumented) -export type OctokitWithPullRequestPluginClient = Octokit & { - createPullRequest(options: createPullRequest.Options): Promise<{ - data: { - html_url: string; - number: number; - base: { - ref: string; - }; - }; - } | null>; -}; - // @public export interface RouterOptions { // (undocumented) diff --git a/plugins/scaffolder-node/api-report.md b/plugins/scaffolder-node/api-report.md index 08caf36812..ca1b9e8b4e 100644 --- a/plugins/scaffolder-node/api-report.md +++ b/plugins/scaffolder-node/api-report.md @@ -10,6 +10,7 @@ import { JsonValue } from '@backstage/types'; import { Logger } from 'winston'; import { Observable } from '@backstage/types'; import { Schema } from 'jsonschema'; +import { ScmIntegrationRegistry } from '@backstage/integration'; import { ScmIntegrations } from '@backstage/integration'; import { SpawnOptionsWithoutStdio } from 'child_process'; import { TaskSpec } from '@backstage/plugin-scaffolder-common'; @@ -44,6 +45,37 @@ export type ActionContext< each?: JsonObject; }; +// @public (undocumented) +export function commitAndPushRepo({ + dir, + auth, + logger, + commitMessage, + gitAuthorInfo, + branch, + remoteRef, +}: { + dir: string; + auth: + | { + username: string; + password: string; + } + | { + token: string; + }; + logger: Logger; + commitMessage: string; + gitAuthorInfo?: { + name?: string; + email?: string; + }; + branch?: string; + remoteRef?: string; +}): Promise<{ + commitHash: string; +}>; + // @public export const createTemplateAction: < TInputParams extends JsonObject = JsonObject, @@ -73,6 +105,12 @@ export const createTemplateAction: < >, ) => TemplateAction; +// @public +export function deserializeDirectoryContents( + targetPath: string, + files: SerializedFile[], +): Promise; + // @public export function executeShellCommand( options: ExecuteShellCommandOptions, @@ -104,6 +142,77 @@ export function fetchFile(options: { outputPath: string; }): Promise; +// @public (undocumented) +export const getRepoSourceDirectory: ( + workspacePath: string, + sourcePath: string | undefined, +) => string; + +// @public (undocumented) +export function initRepoAndPush({ + dir, + remoteUrl, + auth, + logger, + defaultBranch, + commitMessage, + gitAuthorInfo, +}: { + dir: string; + remoteUrl: string; + auth: + | { + username: string; + password: string; + } + | { + token: string; + }; + logger: Logger; + defaultBranch?: string; + commitMessage?: string; + gitAuthorInfo?: { + name?: string; + email?: string; + }; +}): Promise<{ + commitHash: string; +}>; + +// @public (undocumented) +export const parseRepoUrl: ( + repoUrl: string, + integrations: ScmIntegrationRegistry, +) => { + repo: string; + host: string; + owner?: string | undefined; + organization?: string | undefined; + workspace?: string | undefined; + project?: string | undefined; +}; + +// @public (undocumented) +export interface SerializedFile { + // (undocumented) + content: Buffer; + // (undocumented) + executable?: boolean; + // (undocumented) + path: string; + // (undocumented) + symlink?: boolean; +} + +// @public (undocumented) +export function serializeDirectoryContents( + sourcePath: string, + options?: { + gitignore?: boolean; + globPatterns?: string[]; + }, +): Promise; + // @public export type SerializedTask = { id: string; diff --git a/plugins/scaffolder-node/src/actions/repoHelpers.ts b/plugins/scaffolder-node/src/actions/gitHelpers.ts similarity index 98% rename from plugins/scaffolder-node/src/actions/repoHelpers.ts rename to plugins/scaffolder-node/src/actions/gitHelpers.ts index a814ca38ed..770440dba3 100644 --- a/plugins/scaffolder-node/src/actions/repoHelpers.ts +++ b/plugins/scaffolder-node/src/actions/gitHelpers.ts @@ -17,6 +17,9 @@ import { Git } from '@backstage/backend-common'; import { Logger } from 'winston'; +/** + * @public + */ export async function initRepoAndPush({ dir, remoteUrl, @@ -75,6 +78,9 @@ export async function initRepoAndPush({ return { commitHash }; } +/** + * @public + */ export async function commitAndPushRepo({ dir, auth, diff --git a/plugins/scaffolder-node/src/actions/index.ts b/plugins/scaffolder-node/src/actions/index.ts index 27046bebaf..74a0bb61f9 100644 --- a/plugins/scaffolder-node/src/actions/index.ts +++ b/plugins/scaffolder-node/src/actions/index.ts @@ -25,5 +25,5 @@ export { } from './executeShellCommand'; export { fetchContents, fetchFile } from './fetch'; export { type ActionContext, type TemplateAction } from './types'; -export { initRepoAndPush, commitAndPushRepo } from './repoHelpers'; +export { initRepoAndPush, commitAndPushRepo } from './gitHelpers'; export { parseRepoUrl, getRepoSourceDirectory } from './util'; diff --git a/plugins/scaffolder-node/src/actions/util.ts b/plugins/scaffolder-node/src/actions/util.ts index cdd8512e63..327cfa9c2f 100644 --- a/plugins/scaffolder-node/src/actions/util.ts +++ b/plugins/scaffolder-node/src/actions/util.ts @@ -19,6 +19,9 @@ import { isChildPath } from '@backstage/backend-common'; import { join as joinPath, normalize as normalizePath } from 'path'; import { ScmIntegrationRegistry } from '@backstage/integration'; +/** + * @public + */ export const getRepoSourceDirectory = ( workspacePath: string, sourcePath: string | undefined, @@ -37,6 +40,9 @@ export const getRepoSourceDirectory = ( return workspacePath; }; +/** + * @public + */ export const parseRepoUrl = ( repoUrl: string, integrations: ScmIntegrationRegistry, diff --git a/plugins/scaffolder-node/src/files/deserializeDirectoryContents.ts b/plugins/scaffolder-node/src/files/deserializeDirectoryContents.ts index cb567eed9d..bdcecd99f1 100644 --- a/plugins/scaffolder-node/src/files/deserializeDirectoryContents.ts +++ b/plugins/scaffolder-node/src/files/deserializeDirectoryContents.ts @@ -25,7 +25,7 @@ import { SerializedFile } from './types'; * This method uses `resolveSafeChildPath` to make sure that files are * not written outside of the target directory. * - * @internal + * @public */ export async function deserializeDirectoryContents( targetPath: string, diff --git a/plugins/scaffolder-node/src/files/serializeDirectoryContents.ts b/plugins/scaffolder-node/src/files/serializeDirectoryContents.ts index 1197db000a..7e52f6323b 100644 --- a/plugins/scaffolder-node/src/files/serializeDirectoryContents.ts +++ b/plugins/scaffolder-node/src/files/serializeDirectoryContents.ts @@ -41,6 +41,9 @@ async function asyncFilter( return array.filter((_value, index) => filterMap[index]); } +/** + * @public + */ export async function serializeDirectoryContents( sourcePath: string, options?: { diff --git a/plugins/scaffolder-node/src/files/types.ts b/plugins/scaffolder-node/src/files/types.ts index d3a1eaa008..cd471a7881 100644 --- a/plugins/scaffolder-node/src/files/types.ts +++ b/plugins/scaffolder-node/src/files/types.ts @@ -14,6 +14,9 @@ * limitations under the License. */ +/** + * @public + */ export interface SerializedFile { path: string; content: Buffer; diff --git a/plugins/scaffolder-react/src/components/types.ts b/plugins/scaffolder-react/src/components/types.ts index e9ec3bf711..597998bac4 100644 --- a/plugins/scaffolder-react/src/components/types.ts +++ b/plugins/scaffolder-react/src/components/types.ts @@ -23,7 +23,6 @@ import { JsonObject } from '@backstage/types'; export type TemplateGroupFilter = { title?: React.ReactNode; filter: (entity: TemplateEntityV1beta3) => boolean; - sort?: (a: TemplateEntityV1beta3, b: TemplateEntityV1beta3) => number; }; /** From 219d7f0ca77118632c42da5a0d16849fc2b1ba02 Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 6 Dec 2023 14:32:07 +0100 Subject: [PATCH 093/275] chore: add changesets Signed-off-by: blam --- .changeset/clever-rats-smoke.md | 5 +++++ .changeset/kind-eels-sing.md | 6 ++++++ .changeset/long-trainers-matter.md | 5 +++++ .changeset/shiny-cheetahs-vanish.md | 8 ++++++++ 4 files changed, 24 insertions(+) create mode 100644 .changeset/clever-rats-smoke.md create mode 100644 .changeset/kind-eels-sing.md create mode 100644 .changeset/long-trainers-matter.md create mode 100644 .changeset/shiny-cheetahs-vanish.md diff --git a/.changeset/clever-rats-smoke.md b/.changeset/clever-rats-smoke.md new file mode 100644 index 0000000000..9374e325f2 --- /dev/null +++ b/.changeset/clever-rats-smoke.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-gitlab': patch +--- + +Extract some more actions to this library diff --git a/.changeset/kind-eels-sing.md b/.changeset/kind-eels-sing.md new file mode 100644 index 0000000000..3f95a62d60 --- /dev/null +++ b/.changeset/kind-eels-sing.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +'@backstage/plugin-scaffolder-node': patch +--- + +Refactor some methods to `-node` instead and use the new external modules diff --git a/.changeset/long-trainers-matter.md b/.changeset/long-trainers-matter.md new file mode 100644 index 0000000000..92daf131b4 --- /dev/null +++ b/.changeset/long-trainers-matter.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Updating template generation for scaffolder module diff --git a/.changeset/shiny-cheetahs-vanish.md b/.changeset/shiny-cheetahs-vanish.md new file mode 100644 index 0000000000..38c88bdb23 --- /dev/null +++ b/.changeset/shiny-cheetahs-vanish.md @@ -0,0 +1,8 @@ +--- +'@backstage/plugin-scaffolder-backend-module-bitbucket': minor +'@backstage/plugin-scaffolder-backend-module-gerrit': minor +'@backstage/plugin-scaffolder-backend-module-github': minor +'@backstage/plugin-scaffolder-backend-module-azure': minor +--- + +Create new scaffolder module for external integrations From 5e0c1f36e21b229ab854f9b511aa02499dffb7de Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 6 Dec 2023 14:44:54 +0100 Subject: [PATCH 094/275] chore: updating catalog-info.yaml Signed-off-by: blam --- .../scaffolder-backend-module-azure/catalog-info.yaml | 10 ++++++++++ .../catalog-info.yaml | 10 ++++++++++ .../scaffolder-backend-module-gerrit/catalog-info.yaml | 10 ++++++++++ .../scaffolder-backend-module-github/catalog-info.yaml | 10 ++++++++++ plugins/scaffolder-backend/package.json | 2 +- yarn.lock | 2 +- 6 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 plugins/scaffolder-backend-module-azure/catalog-info.yaml create mode 100644 plugins/scaffolder-backend-module-bitbucket/catalog-info.yaml create mode 100644 plugins/scaffolder-backend-module-gerrit/catalog-info.yaml create mode 100644 plugins/scaffolder-backend-module-github/catalog-info.yaml diff --git a/plugins/scaffolder-backend-module-azure/catalog-info.yaml b/plugins/scaffolder-backend-module-azure/catalog-info.yaml new file mode 100644 index 0000000000..16ae855eae --- /dev/null +++ b/plugins/scaffolder-backend-module-azure/catalog-info.yaml @@ -0,0 +1,10 @@ +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: backstage-plugin-scaffolder-backend-module-azure + title: '@backstage/plugin-scaffolder-backend-module-azure' + description: The azure module for @backstage/plugin-scaffolder-backend +spec: + lifecycle: experimental + type: backstage-backend-plugin-module + owner: maintainers diff --git a/plugins/scaffolder-backend-module-bitbucket/catalog-info.yaml b/plugins/scaffolder-backend-module-bitbucket/catalog-info.yaml new file mode 100644 index 0000000000..b0a94d1c13 --- /dev/null +++ b/plugins/scaffolder-backend-module-bitbucket/catalog-info.yaml @@ -0,0 +1,10 @@ +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: backstage-plugin-scaffolder-backend-module-bitbucket + title: '@backstage/plugin-scaffolder-backend-module-bitbucket' + description: The bitbucket module for @backstage/plugin-scaffolder-backend +spec: + lifecycle: experimental + type: backstage-backend-plugin-module + owner: maintainers diff --git a/plugins/scaffolder-backend-module-gerrit/catalog-info.yaml b/plugins/scaffolder-backend-module-gerrit/catalog-info.yaml new file mode 100644 index 0000000000..3eeb8a9018 --- /dev/null +++ b/plugins/scaffolder-backend-module-gerrit/catalog-info.yaml @@ -0,0 +1,10 @@ +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: backstage-plugin-scaffolder-backend-module-gerrit + title: '@backstage/plugin-scaffolder-backend-module-gerrit' + description: The gerrit module for @backstage/plugin-scaffolder-backend +spec: + lifecycle: experimental + type: backstage-backend-plugin-module + owner: maintainers diff --git a/plugins/scaffolder-backend-module-github/catalog-info.yaml b/plugins/scaffolder-backend-module-github/catalog-info.yaml new file mode 100644 index 0000000000..5e70704940 --- /dev/null +++ b/plugins/scaffolder-backend-module-github/catalog-info.yaml @@ -0,0 +1,10 @@ +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: backstage-plugin-scaffolder-backend-module-github + title: '@backstage/plugin-scaffolder-backend-module-github' + description: The github module for @backstage/plugin-scaffolder-backend +spec: + lifecycle: experimental + type: backstage-backend-plugin-module + owner: maintainers diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index 17f293f313..796c177caa 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -71,7 +71,6 @@ "@backstage/types": "workspace:^", "@types/express": "^4.17.6", "@types/luxon": "^3.0.0", - "azure-devops-node-api": "^11.0.1", "command-exists": "^1.2.9", "compression": "^1.7.4", "cors": "^2.8.5", @@ -100,6 +99,7 @@ "zod": "^3.21.4" }, "devDependencies": { + "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@types/command-exists": "^1.2.0", "@types/fs-extra": "^9.0.1", diff --git a/yarn.lock b/yarn.lock index cc201b6204..8931801fe7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8804,6 +8804,7 @@ __metadata: "@backstage/backend-common": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-tasks": "workspace:^" + "@backstage/backend-test-utils": "workspace:^" "@backstage/catalog-client": "workspace:^" "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" @@ -8833,7 +8834,6 @@ __metadata: "@types/nunjucks": ^3.1.4 "@types/supertest": ^2.0.8 "@types/zen-observable": ^0.8.0 - azure-devops-node-api: ^11.0.1 command-exists: ^1.2.9 compression: ^1.7.4 cors: ^2.8.5 From 972ca1df60c242f3319d3b986b5be8700630d90a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Dec 2023 13:55:03 +0000 Subject: [PATCH 095/275] chore(deps): update dependency @types/react to v18.2.42 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index b1d47a2219..68317aec3c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18981,13 +18981,13 @@ __metadata: linkType: hard "@types/react@npm:^18": - version: 18.2.40 - resolution: "@types/react@npm:18.2.40" + version: 18.2.42 + resolution: "@types/react@npm:18.2.42" dependencies: "@types/prop-types": "*" "@types/scheduler": "*" csstype: ^3.0.2 - checksum: c1d8cf29bc314e2d04203b4afe5673aea4ddec39a685c6aff72b01f5b01ae84fed6e994b5e1dbb9fbe4bc69625fdb65a295fae656a2ca9f6a8c949afb327b644 + checksum: d2019afdf48303a3a598a97cc9dd2284e3c04b369e791f6ba3c33232b7f8645daff97b093a19f8b3ce75ac8a261b47552cb4513226ab16d843eb9443b0f91844 languageName: node linkType: hard From 73bae47644cb143511239d89f658563e90a286be Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Dec 2023 13:55:31 +0000 Subject: [PATCH 096/275] chore(deps): update dependency @types/react-helmet to v6.1.11 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index b1d47a2219..d942ab6678 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18897,11 +18897,11 @@ __metadata: linkType: hard "@types/react-helmet@npm:^6.1.0": - version: 6.1.9 - resolution: "@types/react-helmet@npm:6.1.9" + version: 6.1.11 + resolution: "@types/react-helmet@npm:6.1.11" dependencies: "@types/react": "*" - checksum: 4f96b338b6500042a1dde6e7af0e109df91f5ec52a1200dd9511748f85cd659b22e84b51677f86fb1c319dd9e0da56c6947b7130cb1f8989a8ff8e5c2cc26007 + checksum: e329d8ad82c365fec7dd7d91c8b6d167faac30cef0d9f1e27d7e895172a0ebfa65829fb4acabbe79283b01cbbe5840a845caeb50148ceef6f3fad42b3c2c4bdc languageName: node linkType: hard From 7640fe49572387c60f18f0ca915377a7ba388ec7 Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 6 Dec 2023 15:06:18 +0100 Subject: [PATCH 097/275] chore: re-exported of the types Signed-off-by: blam --- plugins/scaffolder-backend/api-report.md | 101 ++++++ .../src/scaffolder/actions/deprecated.ts | 126 ++++++++ .../src/scaffolder/actions/index.ts | 2 + .../src/actions/gitHelpers.test.ts | 305 ++++++++++++++++++ 4 files changed, 534 insertions(+) create mode 100644 plugins/scaffolder-backend/src/scaffolder/actions/deprecated.ts create mode 100644 plugins/scaffolder-node/src/actions/gitHelpers.test.ts diff --git a/plugins/scaffolder-backend/api-report.md b/plugins/scaffolder-backend/api-report.md index 72af83aa6b..c928e5341e 100644 --- a/plugins/scaffolder-backend/api-report.md +++ b/plugins/scaffolder-backend/api-report.md @@ -4,6 +4,8 @@ ```ts import { ActionContext as ActionContext_2 } from '@backstage/plugin-scaffolder-node'; +import * as azure from '@backstage/plugin-scaffolder-backend-module-azure'; +import * as bitbucket from '@backstage/plugin-scaffolder-backend-module-bitbucket'; import { CatalogApi } from '@backstage/catalog-client'; import { Config } from '@backstage/config'; import { Duration } from 'luxon'; @@ -11,6 +13,9 @@ import { executeShellCommand as executeShellCommand_2 } from '@backstage/plugin- import { ExecuteShellCommandOptions } from '@backstage/plugin-scaffolder-node'; import express from 'express'; import { fetchContents as fetchContents_2 } from '@backstage/plugin-scaffolder-node'; +import * as gerrit from '@backstage/plugin-scaffolder-backend-module-gerrit'; +import * as github from '@backstage/plugin-scaffolder-backend-module-github'; +import * as gitlab from '@backstage/plugin-scaffolder-backend-module-gitlab'; import { HumanDuration } from '@backstage/types'; import { IdentityApi } from '@backstage/plugin-auth-node'; import { JsonObject } from '@backstage/types'; @@ -25,6 +30,7 @@ import { RESOURCE_TYPE_SCAFFOLDER_ACTION } from '@backstage/plugin-scaffolder-co import { RESOURCE_TYPE_SCAFFOLDER_TEMPLATE } from '@backstage/plugin-scaffolder-common/alpha'; import { ScaffolderEntitiesProcessor as ScaffolderEntitiesProcessor_2 } from '@backstage/plugin-catalog-backend-module-scaffolder-entity-model'; import { Schema } from 'jsonschema'; +import { ScmIntegrationRegistry } from '@backstage/integration'; import { ScmIntegrations } from '@backstage/integration'; import { SerializedTask as SerializedTask_2 } from '@backstage/plugin-scaffolder-node'; import { SerializedTaskEvent as SerializedTaskEvent_2 } from '@backstage/plugin-scaffolder-node'; @@ -193,6 +199,101 @@ export const createFilesystemRenameAction: () => TemplateAction_2< JsonObject >; +// @public @deprecated (undocumented) +export const createGithubActionsDispatchAction: typeof github.createGithubActionsDispatchAction; + +// @public @deprecated (undocumented) +export const createGithubDeployKeyAction: typeof github.createGithubDeployKeyAction; + +// @public @deprecated (undocumented) +export const createGithubEnvironmentAction: typeof github.createGithubEnvironmentAction; + +// @public @deprecated (undocumented) +export const createGithubIssuesLabelAction: typeof github.createGithubIssuesLabelAction; + +// @public @deprecated (undocumented) +export type CreateGithubPullRequestActionOptions = + github.CreateGithubPullRequestActionOptions; + +// @public @deprecated (undocumented) +export const createGithubRepoCreateAction: typeof github.createGithubRepoCreateAction; + +// @public @deprecated (undocumented) +export const createGithubRepoPushAction: typeof github.createGithubRepoPushAction; + +// @public @deprecated (undocumented) +export const createGithubWebhookAction: typeof github.createGithubWebhookAction; + +// @public @deprecated (undocumented) +export const createPublishAzureAction: typeof azure.createPublishAzureAction; + +// @public @deprecated (undocumented) +export const createPublishBitbucketAction: typeof bitbucket.createPublishBitbucketAction; + +// @public @deprecated (undocumented) +export const createPublishBitbucketCloudAction: typeof bitbucket.createPublishBitbucketCloudAction; + +// @public @deprecated (undocumented) +export const createPublishBitbucketServerAction: typeof bitbucket.createPublishBitbucketServerAction; + +// @public @deprecated (undocumented) +export const createPublishBitbucketServerPullRequestAction: typeof bitbucket.createPublishBitbucketServerPullRequestAction; + +// @public @deprecated (undocumented) +export const createPublishGerritAction: typeof gerrit.createPublishGerritAction; + +// @public @deprecated (undocumented) +export const createPublishGerritReviewAction: typeof gerrit.createPublishGerritReviewAction; + +// @public @deprecated (undocumented) +export const createPublishGithubAction: typeof github.createPublishGithubAction; + +// @public @deprecated (undocumented) +export const createPublishGithubPullRequestAction: ( + options: github.CreateGithubPullRequestActionOptions, +) => TemplateAction_2< + { + title: string; + branchName: string; + targetBranchName?: string | undefined; + description: string; + repoUrl: string; + draft?: boolean | undefined; + targetPath?: string | undefined; + sourcePath?: string | undefined; + token?: string | undefined; + reviewers?: string[] | undefined; + teamReviewers?: string[] | undefined; + commitMessage?: string | undefined; + update?: boolean | undefined; + }, + JsonObject +>; + +// @public @deprecated (undocumented) +export const createPublishGitlabAction: typeof gitlab.createPublishGitlabAction; + +// @public @deprecated (undocumented) +export const createPublishGitlabMergeRequestAction: (options: { + integrations: ScmIntegrationRegistry; +}) => TemplateAction_2< + { + repoUrl: string; + title: string; + description: string; + branchName: string; + targetBranchName?: string | undefined; + sourcePath?: string | undefined; + targetPath?: string | undefined; + token?: string | undefined; + commitAction?: 'update' | 'delete' | 'create' | undefined; + projectid?: string | undefined; + removeSourceBranch?: boolean | undefined; + assignee?: string | undefined; + }, + JsonObject +>; + // @public export function createRouter(options: RouterOptions): Promise; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/deprecated.ts b/plugins/scaffolder-backend/src/scaffolder/actions/deprecated.ts new file mode 100644 index 0000000000..d5a13fbf6d --- /dev/null +++ b/plugins/scaffolder-backend/src/scaffolder/actions/deprecated.ts @@ -0,0 +1,126 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import * as github from '@backstage/plugin-scaffolder-backend-module-github'; +import * as gitlab from '@backstage/plugin-scaffolder-backend-module-gitlab'; +import * as azure from '@backstage/plugin-scaffolder-backend-module-azure'; +import * as bitbucket from '@backstage/plugin-scaffolder-backend-module-bitbucket'; +import * as gerrit from '@backstage/plugin-scaffolder-backend-module-gerrit'; + +/** + * @public @deprecated use import from \@backstage/plugin-scaffolder-backend-module-github instead + */ +export const createGithubActionsDispatchAction = + github.createGithubActionsDispatchAction; + +/** + * @public @deprecated use import from \@backstage/plugin-scaffolder-backend-module-github instead + */ +export const createGithubDeployKeyAction = github.createGithubDeployKeyAction; + +/** + * @public @deprecated use import from \@backstage/plugin-scaffolder-backend-module-github instead + */ +export const createGithubEnvironmentAction = + github.createGithubEnvironmentAction; + +/** + * @public @deprecated use import from \@backstage/plugin-scaffolder-backend-module-github instead + */ +export const createGithubIssuesLabelAction = + github.createGithubIssuesLabelAction; + +/** + * @public @deprecated use import from \@backstage/plugin-scaffolder-backend-module-github instead + */ +export type CreateGithubPullRequestActionOptions = + github.CreateGithubPullRequestActionOptions; + +/** + * @public @deprecated use import from \@backstage/plugin-scaffolder-backend-module-github instead + */ +export const createGithubRepoCreateAction = github.createGithubRepoCreateAction; + +/** + * @public @deprecated use import from \@backstage/plugin-scaffolder-backend-module-github instead + */ +export const createGithubRepoPushAction = github.createGithubRepoPushAction; + +/** + * @public @deprecated use import from \@backstage/plugin-scaffolder-backend-module-github instead + */ +export const createGithubWebhookAction = github.createGithubWebhookAction; + +/** + * @public @deprecated use import from \@backstage/plugin-scaffolder-backend-module-github instead + */ +export const createPublishGithubAction = github.createPublishGithubAction; + +/** + * @public @deprecated use import from \@backstage/plugin-scaffolder-backend-module-github instead + */ +export const createPublishGithubPullRequestAction = + github.createPublishGithubPullRequestAction; + +/** + * @public @deprecated use import from \@backstage/plugin-scaffolder-backend-module-bitbucket instead + */ +export const createPublishBitbucketAction = + bitbucket.createPublishBitbucketAction; + +/** + * @public @deprecated use import from \@backstage/plugin-scaffolder-backend-module-bitbucket instead + */ +export const createPublishBitbucketCloudAction = + bitbucket.createPublishBitbucketCloudAction; + +/** + * @public @deprecated use import from \@backstage/plugin-scaffolder-backend-module-bitbucket instead + */ +export const createPublishBitbucketServerAction = + bitbucket.createPublishBitbucketServerAction; + +/** + * @public @deprecated use import from \@backstage/plugin-scaffolder-backend-module-bitbucket instead + */ +export const createPublishBitbucketServerPullRequestAction = + bitbucket.createPublishBitbucketServerPullRequestAction; + +/** + * @public @deprecated use import from \@backstage/plugin-scaffolder-backend-module-azure instead + */ +export const createPublishAzureAction = azure.createPublishAzureAction; + +/** + * @public @deprecated use import from \@backstage/plugin-scaffolder-backend-module-gerrit instead + */ +export const createPublishGerritAction = gerrit.createPublishGerritAction; + +/** + * @public @deprecated use import from \@backstage/plugin-scaffolder-backend-module-gerrit instead + */ +export const createPublishGerritReviewAction = + gerrit.createPublishGerritReviewAction; + +/** + * @public @deprecated use import from \@backstage/plugin-scaffolder-backend-module-gitlab instead + */ +export const createPublishGitlabAction = gitlab.createPublishGitlabAction; + +/** + * @public @deprecated use import from \@backstage/plugin-scaffolder-backend-module-gitlab instead + */ +export const createPublishGitlabMergeRequestAction = + gitlab.createPublishGitlabMergeRequestAction; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/index.ts b/plugins/scaffolder-backend/src/scaffolder/actions/index.ts index 9ea0607f06..8fdad68499 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/index.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/index.ts @@ -15,4 +15,6 @@ */ export * from './builtin'; +export * from './deprecated'; + export { TemplateActionRegistry } from './TemplateActionRegistry'; diff --git a/plugins/scaffolder-node/src/actions/gitHelpers.test.ts b/plugins/scaffolder-node/src/actions/gitHelpers.test.ts new file mode 100644 index 0000000000..7bc3f64f46 --- /dev/null +++ b/plugins/scaffolder-node/src/actions/gitHelpers.test.ts @@ -0,0 +1,305 @@ +/* + * 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 { Git, getVoidLogger } from '@backstage/backend-common'; +import { commitAndPushRepo, initRepoAndPush } from './gitHelpers'; + +jest.mock('@backstage/backend-common', () => ({ + Git: { + fromAuth: jest.fn().mockReturnValue({ + init: jest.fn(), + add: jest.fn(), + checkout: jest.fn(), + commit: jest + .fn() + .mockResolvedValue('220f19cc36b551763d157f1b5e4a4b446165dbd6'), + fetch: jest.fn(), + addRemote: jest.fn(), + push: jest.fn(), + }), + }, + getVoidLogger: jest.requireActual('@backstage/backend-common').getVoidLogger, +})); + +const mockedGit = Git.fromAuth({ + logger: getVoidLogger(), +}); + +describe('initRepoAndPush', () => { + afterEach(() => { + jest.clearAllMocks(); + }); + + describe('with minimal parameters', () => { + beforeEach(async () => { + await initRepoAndPush({ + dir: '/test/repo/dir/', + remoteUrl: 'git@github.com:test/repo.git', + auth: { + username: 'test-user', + password: 'test-password', + }, + logger: getVoidLogger(), + }); + }); + + it('initializes the repo', () => { + expect(mockedGit.init).toHaveBeenCalledWith({ + dir: '/test/repo/dir/', + defaultBranch: 'master', + }); + }); + + it('stages all files in the repo', () => { + expect(mockedGit.add).toHaveBeenCalledWith({ + dir: '/test/repo/dir/', + filepath: '.', + }); + }); + + it('creates an initial commit', () => { + expect(mockedGit.commit).toHaveBeenCalledWith({ + dir: '/test/repo/dir/', + message: 'Initial commit', + author: { + name: 'Scaffolder', + email: 'scaffolder@backstage.io', + }, + committer: { + name: 'Scaffolder', + email: 'scaffolder@backstage.io', + }, + }); + }); + + it('adds the appropriate remote', () => { + expect(mockedGit.addRemote).toHaveBeenCalledWith({ + dir: '/test/repo/dir/', + url: 'git@github.com:test/repo.git', + remote: 'origin', + }); + }); + + it('pushes to the remote', () => { + expect(mockedGit.push).toHaveBeenCalledWith({ + dir: '/test/repo/dir/', + remote: 'origin', + }); + }); + }); + + it('with token', async () => { + await initRepoAndPush({ + dir: '/test/repo/dir/', + remoteUrl: 'git@github.com:test/repo.git', + auth: { + token: 'test-token', + }, + logger: getVoidLogger(), + }); + + expect(mockedGit.init).toHaveBeenCalledWith({ + dir: '/test/repo/dir/', + defaultBranch: 'master', + }); + }); + + it('allows overriding the default branch', async () => { + await initRepoAndPush({ + dir: '/test/repo/dir/', + defaultBranch: 'trunk', + remoteUrl: 'git@github.com:test/repo.git', + auth: { + username: 'test-user', + password: 'test-password', + }, + logger: getVoidLogger(), + }); + + expect(mockedGit.init).toHaveBeenCalledWith({ + dir: '/test/repo/dir/', + defaultBranch: 'trunk', + }); + }); + + it('allows overriding the author', async () => { + await initRepoAndPush({ + dir: '/test/repo/dir/', + gitAuthorInfo: { + name: 'Custom Scaffolder Author', + email: 'scaffolder@example.org', + }, + remoteUrl: 'git@github.com:test/repo.git', + auth: { + username: 'test-user', + password: 'test-password', + }, + logger: getVoidLogger(), + }); + + expect(mockedGit.commit).toHaveBeenCalledWith({ + dir: '/test/repo/dir/', + message: 'Initial commit', + author: { + name: 'Custom Scaffolder Author', + email: 'scaffolder@example.org', + }, + committer: { + name: 'Custom Scaffolder Author', + email: 'scaffolder@example.org', + }, + }); + }); +}); + +describe('commitAndPushRepo', () => { + afterEach(() => { + jest.clearAllMocks(); + }); + + describe('with minimal parameters', () => { + beforeEach(async () => { + await commitAndPushRepo({ + dir: '/test/repo/dir/', + auth: { + username: 'test-user', + password: 'test-password', + }, + logger: getVoidLogger(), + commitMessage: 'commit message', + }); + }); + + it('fetches commits', () => { + expect(mockedGit.fetch).toHaveBeenCalledWith({ + dir: '/test/repo/dir/', + }); + }); + + it('checkouts to master', () => { + expect(mockedGit.checkout).toHaveBeenCalledWith({ + dir: '/test/repo/dir/', + ref: 'master', + }); + }); + + it('stages all files in the repo', () => { + expect(mockedGit.add).toHaveBeenCalledWith({ + dir: '/test/repo/dir/', + filepath: '.', + }); + }); + + it('creates a commit', () => { + expect(mockedGit.commit).toHaveBeenCalledWith({ + dir: '/test/repo/dir/', + message: 'commit message', + author: { + name: 'Scaffolder', + email: 'scaffolder@backstage.io', + }, + committer: { + name: 'Scaffolder', + email: 'scaffolder@backstage.io', + }, + }); + }); + + it('pushes to the remote', () => { + expect(mockedGit.push).toHaveBeenCalledWith({ + dir: '/test/repo/dir/', + remote: 'origin', + remoteRef: 'refs/heads/master', + }); + }); + }); + + it('allows overriding the default branch', async () => { + await commitAndPushRepo({ + dir: '/test/repo/dir/', + auth: { + username: 'test-user', + password: 'test-password', + }, + logger: getVoidLogger(), + commitMessage: 'commit message', + branch: 'otherbranch', + }); + + expect(mockedGit.checkout).toHaveBeenCalledWith({ + dir: '/test/repo/dir/', + ref: 'otherbranch', + }); + expect(mockedGit.push).toHaveBeenCalledWith({ + dir: '/test/repo/dir/', + remote: 'origin', + remoteRef: 'refs/heads/otherbranch', + }); + }); + + it('allows overriding the remote ref', async () => { + await commitAndPushRepo({ + dir: '/test/repo/dir/', + auth: { + username: 'test-user', + password: 'test-password', + }, + logger: getVoidLogger(), + commitMessage: 'commit message', + remoteRef: 'refs/for/master', + }); + + expect(mockedGit.checkout).toHaveBeenCalledWith({ + dir: '/test/repo/dir/', + ref: 'master', + }); + expect(mockedGit.push).toHaveBeenCalledWith({ + dir: '/test/repo/dir/', + remote: 'origin', + remoteRef: 'refs/for/master', + }); + }); + + it('allows overriding the author', async () => { + await commitAndPushRepo({ + dir: '/test/repo/dir/', + commitMessage: 'commit message', + gitAuthorInfo: { + name: 'Custom Scaffolder Author', + email: 'scaffolder@example.org', + }, + auth: { + username: 'test-user', + password: 'test-password', + }, + logger: getVoidLogger(), + branch: 'master', + }); + + expect(mockedGit.commit).toHaveBeenCalledWith({ + dir: '/test/repo/dir/', + message: 'commit message', + author: { + name: 'Custom Scaffolder Author', + email: 'scaffolder@example.org', + }, + committer: { + name: 'Custom Scaffolder Author', + email: 'scaffolder@example.org', + }, + }); + }); +}); From e3c035b7e6358375a2b46e3e21f60effb1837c35 Mon Sep 17 00:00:00 2001 From: "elena.krasnopolskaia" Date: Wed, 6 Dec 2023 15:15:03 +0100 Subject: [PATCH 098/275] send_page_view changed to configurable Signed-off-by: elena.krasnopolskaia --- plugins/analytics-module-ga4/README.md | 1 + .../apis/implementations/AnalyticsApi/GoogleAnalytics4.ts | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/plugins/analytics-module-ga4/README.md b/plugins/analytics-module-ga4/README.md index 93138a8235..2d8c930e30 100644 --- a/plugins/analytics-module-ga4/README.md +++ b/plugins/analytics-module-ga4/README.md @@ -87,6 +87,7 @@ Additional dimensional data can be captured using custom dimensions, like this: attribute names will be prefixed by `a_`. 5. `allowedContexts` and `allowedAttributes` are optional, if not provided, no additional context and attributes will be sent. 6. if `allowedContexts` or `allowedAttributes` is set to '\*', all context and attributes will be sent. +7. `enableSendPageView` is used to send default events and is disabled by default. ```yaml app: diff --git a/plugins/analytics-module-ga4/src/apis/implementations/AnalyticsApi/GoogleAnalytics4.ts b/plugins/analytics-module-ga4/src/apis/implementations/AnalyticsApi/GoogleAnalytics4.ts index fb5bd261da..9abf4719c6 100644 --- a/plugins/analytics-module-ga4/src/apis/implementations/AnalyticsApi/GoogleAnalytics4.ts +++ b/plugins/analytics-module-ga4/src/apis/implementations/AnalyticsApi/GoogleAnalytics4.ts @@ -47,6 +47,7 @@ export class GoogleAnalytics4 implements AnalyticsApi { measurementId: string; testMode: boolean; debug: boolean; + enableSendPageView: boolean; contentGroupBy?: string; allowedContexts?: string[]; allowedAttributes?: string[]; @@ -58,6 +59,7 @@ export class GoogleAnalytics4 implements AnalyticsApi { userIdTransform = 'sha-256', testMode, debug, + enableSendPageView, contentGroupBy, allowedContexts, allowedAttributes, @@ -70,7 +72,7 @@ export class GoogleAnalytics4 implements AnalyticsApi { }, gtagOptions: { debug_mode: debug, - send_page_view: false, + send_page_view: enableSendPageView, }, }); @@ -113,6 +115,9 @@ export class GoogleAnalytics4 implements AnalyticsApi { const identity = config.getOptionalString('app.analytics.ga4.identity') || 'disabled'; const debug = config.getOptionalBoolean('app.analytics.ga4.debug') ?? false; + const enableSendPageView = + config.getOptionalBoolean('app.analytics.ga4.enableSendPageView') ?? + false; const testMode = config.getOptionalBoolean('app.analytics.ga4.testMode') ?? false; @@ -139,6 +144,7 @@ export class GoogleAnalytics4 implements AnalyticsApi { measurementId: measurementId, testMode, debug, + enableSendPageView, contentGroupBy, allowedContexts, allowedAttributes, From 17a506874daf94b0be6662a3b02dbdf0f06edf78 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Dec 2023 14:20:58 +0000 Subject: [PATCH 099/275] chore(deps): update dependency @types/react-syntax-highlighter to v15.5.11 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index ab3b8f3f3e..979cb9f47a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18927,11 +18927,11 @@ __metadata: linkType: hard "@types/react-syntax-highlighter@npm:^15.0.0": - version: 15.5.10 - resolution: "@types/react-syntax-highlighter@npm:15.5.10" + version: 15.5.11 + resolution: "@types/react-syntax-highlighter@npm:15.5.11" dependencies: "@types/react": "*" - checksum: 07da5fa432883130289aac2547bd5ddcb568c33b834983829933067c379ddb9a6de200d10174dabb0b4476ba3fce54761c7c8be1ede8a51cd0c1b1ca9cb6867e + checksum: 8363ded0138963407c909f198ddcac58d9c937b118f16a46fb3e97078dd0c6234746f9efa85f6aa660efebe357bab11047c95b57bd9508dd4b09619b1a237087 languageName: node linkType: hard From 69919a82abf6b6f058740e5483baba3fcddf9856 Mon Sep 17 00:00:00 2001 From: Philipp Hugenroth Date: Wed, 6 Dec 2023 15:27:00 +0100 Subject: [PATCH 100/275] Remove flag from Signed-off-by: Philipp Hugenroth --- .../src/layout/HeaderTabs/HeaderTabs.tsx | 8 ++----- .../src/layout/TabbedCard/TabbedCard.test.tsx | 22 +++++++++++++++++++ .../src/layout/TabbedCard/TabbedCard.tsx | 1 - 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx b/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx index 59a40001ee..799eab1eb5 100644 --- a/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx +++ b/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx @@ -81,14 +81,11 @@ export function HeaderTabs(props: HeaderTabsProps) { const styles = useStyles(); const handleChange = useCallback( - (e: React.ChangeEvent<{}>, index: number) => { + (_: React.ChangeEvent<{}>, index: number) => { if (selectedIndex === undefined) { setSelectedTab(index); } - - if (e.type === 'focus') { - onChange?.(index); - } + if (onChange) onChange(index); }, [selectedIndex, onChange], ); @@ -102,7 +99,6 @@ export function HeaderTabs(props: HeaderTabsProps) { return ( ', () => { ); expect(screen.getByText('Test Content 2')).toBeInTheDocument(); }); + + it('should trigger onChange only once', async () => { + const mockOnChange = jest.fn(); + const user = userEvent.setup(); + + const rendered = render( + wrapInTestApp( + + + Test Content 1 + + + Test Content 2 + + , + ), + ); + + await user.click(rendered.getByText('Test 2')); + expect(mockOnChange).toHaveBeenCalledTimes(1); + }); }); diff --git a/packages/core-components/src/layout/TabbedCard/TabbedCard.tsx b/packages/core-components/src/layout/TabbedCard/TabbedCard.tsx index 4e75878a7d..088e54c1f3 100644 --- a/packages/core-components/src/layout/TabbedCard/TabbedCard.tsx +++ b/packages/core-components/src/layout/TabbedCard/TabbedCard.tsx @@ -114,7 +114,6 @@ export function TabbedCard(props: PropsWithChildren) { {title && } Date: Wed, 6 Dec 2023 17:09:25 +0100 Subject: [PATCH 101/275] Added directions as props to be set for Diagram Signed-off-by: Jasper Boeijenga --- .../components/GroupsExplorerContent/GroupsDiagram.tsx | 6 ++++-- .../GroupsExplorerContent/GroupsExplorerContent.tsx | 8 ++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/plugins/explore/src/components/GroupsExplorerContent/GroupsDiagram.tsx b/plugins/explore/src/components/GroupsExplorerContent/GroupsDiagram.tsx index ea989c2834..f7f0eab0bd 100644 --- a/plugins/explore/src/components/GroupsExplorerContent/GroupsDiagram.tsx +++ b/plugins/explore/src/components/GroupsExplorerContent/GroupsDiagram.tsx @@ -164,7 +164,9 @@ function RenderNode(props: DependencyGraphTypes.RenderNodeProps) { /** * Dynamically generates a diagram of groups registered in the catalog. */ -export function GroupsDiagram() { +export function GroupsDiagram(props: { + direction?: DependencyGraphTypes.Direction; +}) { const nodes = new Array<{ id: string; kind: string; @@ -243,7 +245,7 @@ export function GroupsDiagram() { nodes={nodes} edges={edges} nodeMargin={10} - direction={DependencyGraphTypes.Direction.RIGHT_LEFT} + direction={props.direction || DependencyGraphTypes.Direction.RIGHT_LEFT} renderNode={RenderNode} className={classes.graph} fit="contain" diff --git a/plugins/explore/src/components/GroupsExplorerContent/GroupsExplorerContent.tsx b/plugins/explore/src/components/GroupsExplorerContent/GroupsExplorerContent.tsx index 61757a35b6..27a7f629ad 100644 --- a/plugins/explore/src/components/GroupsExplorerContent/GroupsExplorerContent.tsx +++ b/plugins/explore/src/components/GroupsExplorerContent/GroupsExplorerContent.tsx @@ -19,6 +19,7 @@ import { GroupsDiagram } from './GroupsDiagram'; import { Content, ContentHeader, + DependencyGraphTypes, SupportButton, } from '@backstage/core-components'; import { makeStyles } from '@material-ui/core/styles'; @@ -34,7 +35,10 @@ const useStyles = makeStyles( { name: 'ExploreGroupsContent' }, ); -export const GroupsExplorerContent = (props: { title?: string }) => { +export const GroupsExplorerContent = (props: { + title?: string; + direction?: DependencyGraphTypes.Direction; +}) => { const classes = useStyles(); return ( @@ -42,7 +46,7 @@ export const GroupsExplorerContent = (props: { title?: string }) => { Explore your groups. - + ); }; From aac659efb672681fb61bd8161b30503ac2470744 Mon Sep 17 00:00:00 2001 From: Jasper Boeijenga Date: Wed, 6 Dec 2023 17:11:29 +0100 Subject: [PATCH 102/275] Added changeset Signed-off-by: Jasper Boeijenga --- .changeset/many-days-wash.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/many-days-wash.md diff --git a/.changeset/many-days-wash.md b/.changeset/many-days-wash.md new file mode 100644 index 0000000000..c712b8cd9b --- /dev/null +++ b/.changeset/many-days-wash.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-explore': minor +--- + +Added option to set Direction for the graph in the GroupsDiagram From 59d0f40fd52990334ed3050e99a68ca5f47e3acb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Dec 2023 16:39:39 +0000 Subject: [PATCH 103/275] chore(deps): update dependency better-sqlite3 to v9.2.2 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index fac0abc4ce..9427377ee6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -21533,13 +21533,13 @@ __metadata: linkType: hard "better-sqlite3@npm:^9.0.0": - version: 9.2.0 - resolution: "better-sqlite3@npm:9.2.0" + version: 9.2.2 + resolution: "better-sqlite3@npm:9.2.2" dependencies: bindings: ^1.5.0 node-gyp: latest prebuild-install: ^7.1.1 - checksum: b6e5d8a34b950fa060fc7bb2206ea178d57f1094a2c09e3c7162b03e1cca4b6cf70da4a194fead61233206730154684243211f345de5f1f9a5ad14faf722ee5c + checksum: 11d78ed15c8f059c5b58845c40b921692468cef291975ad9f9395278c6ba3005ae2aceb20175fe18e901983ed68c785fdd39c729dc789d72be4184a406bd9a2c languageName: node linkType: hard From 6d38a07a262888a50fc9dd62d4cafb172656d1c2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Dec 2023 16:40:13 +0000 Subject: [PATCH 104/275] chore(deps): update dependency msw to v2.0.10 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/yarn.lock b/yarn.lock index fac0abc4ce..ea03c4a1a0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13255,9 +13255,9 @@ __metadata: languageName: node linkType: hard -"@mswjs/interceptors@npm:^0.25.11": - version: 0.25.12 - resolution: "@mswjs/interceptors@npm:0.25.12" +"@mswjs/interceptors@npm:^0.25.13": + version: 0.25.13 + resolution: "@mswjs/interceptors@npm:0.25.13" dependencies: "@open-draft/deferred-promise": ^2.2.0 "@open-draft/logger": ^0.3.0 @@ -13265,7 +13265,7 @@ __metadata: is-node-process: ^1.2.0 outvariant: ^1.2.1 strict-event-emitter: ^0.5.1 - checksum: 0676808700059f55536b51ffe38e9ea07e26b4d9c284fbbdf7a52b7282b7a93703f18d93b109c384205fe5f72b585506d5550cc8f3559267892b01a0f7561d3d + checksum: 21eaefbd66dc2c3bbeec5b6a2fdc714f6a0967158c0137cd1e4b875284e55d358b4a032030d5e0783e5826cdb27918086d1fd8412f3cbcc70e5368554f678d46 languageName: node linkType: hard @@ -34773,14 +34773,14 @@ __metadata: linkType: hard "msw@npm:^2.0.0, msw@npm:^2.0.8": - version: 2.0.9 - resolution: "msw@npm:2.0.9" + version: 2.0.10 + resolution: "msw@npm:2.0.10" dependencies: "@bundled-es-modules/cookie": ^2.0.0 "@bundled-es-modules/js-levenshtein": ^2.0.1 "@bundled-es-modules/statuses": ^1.0.1 "@mswjs/cookies": ^1.1.0 - "@mswjs/interceptors": ^0.25.11 + "@mswjs/interceptors": ^0.25.13 "@open-draft/until": ^2.1.0 "@types/cookie": ^0.4.1 "@types/js-levenshtein": ^1.1.1 @@ -34804,7 +34804,7 @@ __metadata: optional: true bin: msw: cli/index.js - checksum: 77bdb10a019f1d382bfc66b3005752e722f2891e9f8a4f9d3d17f5641ca4d8afb02bc67c9325dfd25708702443e0f9b8e48fbc580faa37c21e090425df93089e + checksum: 1f18c835019a0c7c24280777885a9e8878bba0de3be2e7dcc2362c0850e69b18198fb9774ac1cf39690ca7e82b9e59b318b753f79761a91ce55d6659c2289d61 languageName: node linkType: hard From 317338c708901ee36012aaa8193f7cee7977474d Mon Sep 17 00:00:00 2001 From: Aramis Date: Wed, 6 Dec 2023 16:27:43 -0500 Subject: [PATCH 105/275] An unfortunate end. Signed-off-by: Aramis --- OWNERS.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/OWNERS.md b/OWNERS.md index b3f9d7bef9..20d5f6ae91 100644 --- a/OWNERS.md +++ b/OWNERS.md @@ -78,7 +78,6 @@ Scope: The Permission Framework and plugins integrating with the permission fram | Name | Organization | Team | GitHub | Discord | | -------------------- | ------------ | --------------- | ----------------------------------------------- | ---------------- | | Ainhoa Larumbe | Spotify | Imaginary Goats | [ainhoaL](http://github.com/ainhoaL) | ainhoa#8085 | -| Aramis Sennyey | Spotify | Imaginary Goats | [sennyeya](https://github.com/sennyeya) | Aramis#7984 | | Claire Casey | Spotify | Imaginary Goats | [clairelcasey](http://github.com/clairelcasey) | clairecasey#2710 | | Eric Peterson | Spotify | Imaginary Goats | [iamEAP](http://github.com/iamEAP) | iamEAP#3058 | | Harry Hogg | Spotify | Imaginary Goats | [HHogg](http://github.com/HHogg) | simplex#3451 | @@ -118,7 +117,7 @@ Scope: Tooling for frontend and backend schema-first OpenAPI development. | Name | Organization | GitHub | Discord | | -------------- | ------------ | --------------------------------------- | ------------- | -| Aramis Sennyey | Spotify | [sennyeya](https://github.com/sennyeya) | `Aramis#7984` | +| Aramis Sennyey | | [sennyeya](https://github.com/sennyeya) | `Aramis#7984` | ### Scaffolder @@ -147,7 +146,7 @@ Scope: The Scaffolder frontend and backend plugins, and related tooling. | Alex Crome | | [afscrome](https://github.com/afscrome) | `afscrome` | | Andre Wanlin | Spotify | [awanlin](https://github.com/awanlin) | `ahhhndre` | | Andrew Thauer | Wealthsimple | [andrewthauer](https://github.com/andrewthauer) | `andrewthauer#3060` | -| Aramis Sennyey | Spotify | [sennyeya](https://github.com/sennyeya) | `Aramis#7984` | +| Aramis Sennyey | | [sennyeya](https://github.com/sennyeya) | `Aramis#7984` | | Brian Fletcher | Roadie.io | [punkle](https://github.com/punkle) | `Brian Fletcher#7051` | | Carlos Esteban Lopez Jaramillo | VMWare | [luchillo17](https://github.com/luchillo17) | `luchillo17#8777` | | David Tuite | Roadie.io | [dtuite](https://github.com/dtuite) | `David Tuite (roadie.io)#1010` | From 4785d0561ee6525b37493d3b1d8c0b14eb6d7fc1 Mon Sep 17 00:00:00 2001 From: rui ma Date: Fri, 1 Dec 2023 10:59:18 +0800 Subject: [PATCH 106/275] feat: add permission to catalog create and refresh buttion Signed-off-by: rui ma --- .changeset/large-oranges-press.md | 6 ++ plugins/catalog/package.json | 3 +- .../components/AboutCard/AboutCard.test.tsx | 72 +++++++++++++++++++ .../src/components/AboutCard/AboutCard.tsx | 7 +- .../CatalogPage/DefaultCatalogPage.test.tsx | 3 + .../CatalogPage/DefaultCatalogPage.tsx | 15 ++-- plugins/org/package.json | 1 + .../Group/GroupProfile/GroupProfileCard.tsx | 7 +- yarn.lock | 2 + 9 files changed, 109 insertions(+), 7 deletions(-) create mode 100644 .changeset/large-oranges-press.md diff --git a/.changeset/large-oranges-press.md b/.changeset/large-oranges-press.md new file mode 100644 index 0000000000..b59520bf19 --- /dev/null +++ b/.changeset/large-oranges-press.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-catalog': patch +'@backstage/plugin-org': patch +--- + +Add permission check to catalog create and refresh button diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json index 12d66efedb..13beb5b7a4 100644 --- a/plugins/catalog/package.json +++ b/plugins/catalog/package.json @@ -56,6 +56,7 @@ "@backstage/integration-react": "workspace:^", "@backstage/plugin-catalog-common": "workspace:^", "@backstage/plugin-catalog-react": "workspace:^", + "@backstage/plugin-permission-react": "workspace:^", "@backstage/plugin-scaffolder-common": "workspace:^", "@backstage/plugin-search-common": "workspace:^", "@backstage/plugin-search-react": "workspace:^", @@ -83,7 +84,7 @@ "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", "@backstage/dev-utils": "workspace:^", - "@backstage/plugin-permission-react": "workspace:^", + "@backstage/plugin-permission-common": "workspace:^", "@backstage/test-utils": "workspace:^", "@testing-library/dom": "^9.0.0", "@testing-library/jest-dom": "^6.0.0", diff --git a/plugins/catalog/src/components/AboutCard/AboutCard.test.tsx b/plugins/catalog/src/components/AboutCard/AboutCard.test.tsx index 1679e2ddf5..e27de38913 100644 --- a/plugins/catalog/src/components/AboutCard/AboutCard.test.tsx +++ b/plugins/catalog/src/components/AboutCard/AboutCard.test.tsx @@ -33,6 +33,12 @@ import { RELATION_OWNED_BY } from '@backstage/catalog-model'; import React from 'react'; import { screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import { permissionApiRef } from '@backstage/plugin-permission-react'; +import { AuthorizeResult } from '@backstage/plugin-permission-common'; + +const mockAuthorize = jest.fn(); + +const mockPermissionApi = { authorize: mockAuthorize }; describe('', () => { const catalogApi: jest.Mocked = { @@ -87,6 +93,7 @@ describe('', () => { ), ], [catalogApiRef, catalogApi], + [permissionApiRef, {}], ]} > @@ -143,6 +150,7 @@ describe('', () => { ), ], [catalogApiRef, catalogApi], + [permissionApiRef, {}], ]} > @@ -198,6 +206,7 @@ describe('', () => { ), ], [catalogApiRef, catalogApi], + [permissionApiRef, {}], ]} > @@ -240,6 +249,7 @@ describe('', () => { ScmIntegrationsApi.fromConfig(new ConfigReader({})), ], [catalogApiRef, catalogApi], + [permissionApiRef, {}], ]} > @@ -276,6 +286,10 @@ describe('', () => { }, }; + mockAuthorize.mockImplementation(async () => ({ + result: AuthorizeResult.ALLOW, + })); + await renderInTestApp( ', () => { ScmIntegrationsApi.fromConfig(new ConfigReader({})), ], [catalogApiRef, catalogApi], + [permissionApiRef, mockPermissionApi], ]} > @@ -308,6 +323,55 @@ describe('', () => { ); }); + it('should not render refresh button if the permission is DENY', async () => { + const entity = { + apiVersion: 'v1', + kind: 'Component', + metadata: { + annotations: { + 'backstage.io/managed-by-location': + 'url:https://backstage.io/catalog-info.yaml', + }, + name: 'software-deny', + }, + spec: { + owner: 'guest', + type: 'service', + lifecycle: 'production', + }, + }; + + mockAuthorize.mockImplementation(async () => ({ + result: AuthorizeResult.DENY, + })); + + await renderInTestApp( + + + + + , + { + mountedRoutes: { + '/catalog/:namespace/:kind/:name': entityRouteRef, + }, + }, + ); + + expect( + screen.queryByTitle('Schedule entity refresh'), + ).not.toBeInTheDocument(); + }); + it('should not render refresh button if the location is not an url or file', async () => { const entity = { apiVersion: 'v1', @@ -330,6 +394,7 @@ describe('', () => { ScmIntegrationsApi.fromConfig(new ConfigReader({})), ], [catalogApiRef, catalogApi], + [permissionApiRef, {}], ]} > @@ -384,6 +449,7 @@ describe('', () => { ), ], [catalogApiRef, catalogApi], + [permissionApiRef, {}], ]} > @@ -440,6 +506,7 @@ describe('', () => { ), ], [catalogApiRef, catalogApi], + [permissionApiRef, {}], ]} > @@ -493,6 +560,7 @@ describe('', () => { ), ], [catalogApiRef, catalogApi], + [permissionApiRef, {}], ]} > @@ -546,6 +614,7 @@ describe('', () => { ), ], [catalogApiRef, catalogApi], + [permissionApiRef, {}], ]} > @@ -592,6 +661,7 @@ describe('', () => { ), ], [catalogApiRef, catalogApi], + [permissionApiRef, {}], ]} > @@ -659,6 +729,7 @@ describe('', () => { ), ], [catalogApiRef, catalogApi], + [permissionApiRef, {}], ]} > @@ -707,6 +778,7 @@ describe('', () => { ), ], [catalogApiRef, catalogApi], + [permissionApiRef, {}], ]} > diff --git a/plugins/catalog/src/components/AboutCard/AboutCard.tsx b/plugins/catalog/src/components/AboutCard/AboutCard.tsx index 34aa463c39..763f6fc094 100644 --- a/plugins/catalog/src/components/AboutCard/AboutCard.tsx +++ b/plugins/catalog/src/components/AboutCard/AboutCard.tsx @@ -60,6 +60,8 @@ import DocsIcon from '@material-ui/icons/Description'; import EditIcon from '@material-ui/icons/Edit'; import { isTemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; import { parseEntityRef } from '@backstage/catalog-model'; +import { useEntityPermission } from '@backstage/plugin-catalog-react/alpha'; +import { catalogEntityRefreshPermission } from '@backstage/plugin-catalog-common/alpha'; const TECHDOCS_ANNOTATION = 'backstage.io/techdocs-ref'; @@ -108,6 +110,9 @@ export function AboutCard(props: AboutCardProps) { const errorApi = useApi(errorApiRef); const viewTechdocLink = useRouteRef(viewTechDocRouteRef); const templateRoute = useRouteRef(createFromTemplateRouteRef); + const { allowed: canRefresh } = useEntityPermission( + catalogEntityRefreshPermission, + ); const entitySourceLocation = getEntitySourceLocation( entity, @@ -215,7 +220,7 @@ export function AboutCard(props: AboutCardProps) { title="About" action={ <> - {allowRefresh && ( + {allowRefresh && canRefresh && ( { const origReplaceState = window.history.replaceState; @@ -168,6 +170,7 @@ describe('DefaultCatalogPage', () => { [identityApiRef, identityApi], [storageApiRef, storageApi], [starredEntitiesApiRef, new MockStarredEntitiesApi()], + [permissionApiRef, new MockPermissionApi()], ]} > {children} diff --git a/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx index 8dfc29f87f..779b347b48 100644 --- a/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx +++ b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx @@ -45,6 +45,8 @@ import { catalogTranslationRef } from '../../translation'; import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; import { CatalogTableColumnsFunc } from '../CatalogTable/types'; +import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common/alpha'; +import { usePermission } from '@backstage/plugin-permission-react'; /** @internal */ export type BaseCatalogPageProps = { @@ -60,15 +62,20 @@ export function BaseCatalogPage(props: BaseCatalogPageProps) { useApi(configApiRef).getOptionalString('organization.name') ?? 'Backstage'; const createComponentLink = useRouteRef(createComponentRouteRef); const { t } = useTranslationRef(catalogTranslationRef); + const { allowed } = usePermission({ + permission: catalogEntityCreatePermission, + }); return ( - + {allowed && ( + + )} All your software catalog entities diff --git a/plugins/org/package.json b/plugins/org/package.json index 3e006fb958..6f46f44740 100644 --- a/plugins/org/package.json +++ b/plugins/org/package.json @@ -33,6 +33,7 @@ "@backstage/catalog-model": "workspace:^", "@backstage/core-components": "workspace:^", "@backstage/core-plugin-api": "workspace:^", + "@backstage/plugin-catalog-common": "workspace:^", "@backstage/plugin-catalog-react": "workspace:^", "@backstage/theme": "workspace:^", "@material-ui/core": "^4.12.2", diff --git a/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.tsx b/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.tsx index 76527362ff..33c6ee137a 100644 --- a/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.tsx +++ b/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.tsx @@ -54,6 +54,8 @@ import EditIcon from '@material-ui/icons/Edit'; import EmailIcon from '@material-ui/icons/Email'; import GroupIcon from '@material-ui/icons/Group'; import { LinksGroup } from '../../Meta'; +import { useEntityPermission } from '@backstage/plugin-catalog-react/alpha'; +import { catalogEntityRefreshPermission } from '@backstage/plugin-catalog-common/alpha'; const CardTitle = (props: { title: string }) => ( @@ -70,6 +72,9 @@ export const GroupProfileCard = (props: { const catalogApi = useApi(catalogApiRef); const alertApi = useApi(alertApiRef); const { entity: group } = useEntity(); + const { allowed: canRefresh } = useEntityPermission( + catalogEntityRefreshPermission, + ); const refreshEntity = useCallback(async () => { await catalogApi.refreshEntity(stringifyEntityRef(group)); @@ -127,7 +132,7 @@ export const GroupProfileCard = (props: { variant={props.variant} action={ <> - {allowRefresh && ( + {allowRefresh && canRefresh && ( Date: Thu, 7 Dec 2023 09:59:21 +0100 Subject: [PATCH 107/275] chore: removing some packages not necessary Signed-off-by: blam --- plugins/scaffolder-backend/package.json | 13 ------------- yarn.lock | 13 ------------- 2 files changed, 26 deletions(-) diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index 796c177caa..1bc0617131 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -55,9 +55,7 @@ "@backstage/errors": "workspace:^", "@backstage/integration": "workspace:^", "@backstage/plugin-auth-node": "workspace:^", - "@backstage/plugin-catalog-backend": "workspace:^", "@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "workspace:^", - "@backstage/plugin-catalog-common": "workspace:^", "@backstage/plugin-catalog-node": "workspace:^", "@backstage/plugin-permission-common": "workspace:^", "@backstage/plugin-permission-node": "workspace:^", @@ -71,23 +69,16 @@ "@backstage/types": "workspace:^", "@types/express": "^4.17.6", "@types/luxon": "^3.0.0", - "command-exists": "^1.2.9", - "compression": "^1.7.4", - "cors": "^2.8.5", "express": "^4.17.1", "express-promise-router": "^4.1.0", "fs-extra": "10.1.0", - "git-url-parse": "^13.0.0", "globby": "^11.0.0", "isbinaryfile": "^5.0.0", "isolated-vm": "^4.5.0", - "isomorphic-git": "^1.23.0", "jsonschema": "^1.2.6", "knex": "^3.0.0", "lodash": "^4.17.21", "luxon": "^3.0.0", - "morgan": "^1.10.0", - "node-fetch": "^2.6.7", "nunjucks": "^3.2.3", "p-limit": "^3.1.0", "p-queue": "^6.6.2", @@ -101,15 +92,11 @@ "devDependencies": { "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", - "@types/command-exists": "^1.2.0", "@types/fs-extra": "^9.0.1", - "@types/git-url-parse": "^9.0.0", "@types/nunjucks": "^3.1.4", "@types/supertest": "^2.0.8", "@types/zen-observable": "^0.8.0", "esbuild": "^0.19.0", - "jest-when": "^3.1.0", - "msw": "^1.0.0", "strip-ansi": "^7.1.0", "supertest": "^6.1.3", "wait-for-expect": "^3.0.2" diff --git a/yarn.lock b/yarn.lock index 8931801fe7..f302329de7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8812,9 +8812,7 @@ __metadata: "@backstage/errors": "workspace:^" "@backstage/integration": "workspace:^" "@backstage/plugin-auth-node": "workspace:^" - "@backstage/plugin-catalog-backend": "workspace:^" "@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "workspace:^" - "@backstage/plugin-catalog-common": "workspace:^" "@backstage/plugin-catalog-node": "workspace:^" "@backstage/plugin-permission-common": "workspace:^" "@backstage/plugin-permission-node": "workspace:^" @@ -8826,34 +8824,23 @@ __metadata: "@backstage/plugin-scaffolder-common": "workspace:^" "@backstage/plugin-scaffolder-node": "workspace:^" "@backstage/types": "workspace:^" - "@types/command-exists": ^1.2.0 "@types/express": ^4.17.6 "@types/fs-extra": ^9.0.1 - "@types/git-url-parse": ^9.0.0 "@types/luxon": ^3.0.0 "@types/nunjucks": ^3.1.4 "@types/supertest": ^2.0.8 "@types/zen-observable": ^0.8.0 - command-exists: ^1.2.9 - compression: ^1.7.4 - cors: ^2.8.5 esbuild: ^0.19.0 express: ^4.17.1 express-promise-router: ^4.1.0 fs-extra: 10.1.0 - git-url-parse: ^13.0.0 globby: ^11.0.0 isbinaryfile: ^5.0.0 isolated-vm: ^4.5.0 - isomorphic-git: ^1.23.0 - jest-when: ^3.1.0 jsonschema: ^1.2.6 knex: ^3.0.0 lodash: ^4.17.21 luxon: ^3.0.0 - morgan: ^1.10.0 - msw: ^1.0.0 - node-fetch: ^2.6.7 nunjucks: ^3.2.3 p-limit: ^3.1.0 p-queue: ^6.6.2 From 7daf7859817621733c97a286791194d642c70aa1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 7 Dec 2023 09:07:23 +0000 Subject: [PATCH 108/275] chore(deps): update dependency @types/node to v16.18.68 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/yarn.lock b/yarn.lock index 020a4dc43e..63297048a7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18628,11 +18628,11 @@ __metadata: linkType: hard "@types/node@npm:*, @types/node@npm:>=12.12.47, @types/node@npm:>=13.7.0, @types/node@npm:^20.1.1": - version: 20.10.2 - resolution: "@types/node@npm:20.10.2" + version: 20.10.4 + resolution: "@types/node@npm:20.10.4" dependencies: undici-types: ~5.26.4 - checksum: c0c84e8270cdf7a47a18c0230c0321537cc59506adb0e3cba51949b6f1ad4879f2e2ec3a29161f2f5321ebb6415460712d9f0a25ac5c02be0f5435464fe77c23 + checksum: 054b296417e771ab524bea63cf3289559c6bdf290d45428f7cc68e9b00030ff7a0ece47b8c99a26b4f47a443919813bcf42beadff2f0bea7d8125fa541d92eb0 languageName: node linkType: hard @@ -18651,9 +18651,9 @@ __metadata: linkType: hard "@types/node@npm:^16.11.26, @types/node@npm:^16.7.10, @types/node@npm:^16.9.2": - version: 16.18.66 - resolution: "@types/node@npm:16.18.66" - checksum: 84408652068f8c7e3aa1fa6f333be8044ae802a700eb3b4101fc27d047eefcc742e636809a6318fb0100b1355658649f4a0fc2398fb04f27b1a357f6f3579cd0 + version: 16.18.68 + resolution: "@types/node@npm:16.18.68" + checksum: 094ae9ed80eed2af4bd34d551467e307f2ecb6efb0f8b872feebfb9da5ea4b446c5883c9abe2349f8ea2b78bdacd8726a946c27c2a246676c4c330e41ccb9284 languageName: node linkType: hard @@ -18665,11 +18665,11 @@ __metadata: linkType: hard "@types/node@npm:^18.17.8": - version: 18.19.1 - resolution: "@types/node@npm:18.19.1" + version: 18.19.3 + resolution: "@types/node@npm:18.19.3" dependencies: undici-types: ~5.26.4 - checksum: f687338a6f1c463b03232337652804f62f5ae197ae9517a76cf6543ec5a3e358e41f26da0e4fc1afe4871c4a96eec3e3c440fb4ddb616cdc336b42ca203adb29 + checksum: 58c4fa45a78fcec75c78182a4b266395905957633654eb0311c5f9c30ac15c179ea2287ab1af034e46c2db7bb0589ef0000ee64c1de8f568a0aad29eaadb100c languageName: node linkType: hard From f4fa6c8136d7e7a3189455d5421740a24bd62a3d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 7 Dec 2023 09:07:53 +0000 Subject: [PATCH 109/275] chore(deps): update dependency @types/node to v18.19.3 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/yarn.lock b/yarn.lock index 020a4dc43e..63297048a7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18628,11 +18628,11 @@ __metadata: linkType: hard "@types/node@npm:*, @types/node@npm:>=12.12.47, @types/node@npm:>=13.7.0, @types/node@npm:^20.1.1": - version: 20.10.2 - resolution: "@types/node@npm:20.10.2" + version: 20.10.4 + resolution: "@types/node@npm:20.10.4" dependencies: undici-types: ~5.26.4 - checksum: c0c84e8270cdf7a47a18c0230c0321537cc59506adb0e3cba51949b6f1ad4879f2e2ec3a29161f2f5321ebb6415460712d9f0a25ac5c02be0f5435464fe77c23 + checksum: 054b296417e771ab524bea63cf3289559c6bdf290d45428f7cc68e9b00030ff7a0ece47b8c99a26b4f47a443919813bcf42beadff2f0bea7d8125fa541d92eb0 languageName: node linkType: hard @@ -18651,9 +18651,9 @@ __metadata: linkType: hard "@types/node@npm:^16.11.26, @types/node@npm:^16.7.10, @types/node@npm:^16.9.2": - version: 16.18.66 - resolution: "@types/node@npm:16.18.66" - checksum: 84408652068f8c7e3aa1fa6f333be8044ae802a700eb3b4101fc27d047eefcc742e636809a6318fb0100b1355658649f4a0fc2398fb04f27b1a357f6f3579cd0 + version: 16.18.68 + resolution: "@types/node@npm:16.18.68" + checksum: 094ae9ed80eed2af4bd34d551467e307f2ecb6efb0f8b872feebfb9da5ea4b446c5883c9abe2349f8ea2b78bdacd8726a946c27c2a246676c4c330e41ccb9284 languageName: node linkType: hard @@ -18665,11 +18665,11 @@ __metadata: linkType: hard "@types/node@npm:^18.17.8": - version: 18.19.1 - resolution: "@types/node@npm:18.19.1" + version: 18.19.3 + resolution: "@types/node@npm:18.19.3" dependencies: undici-types: ~5.26.4 - checksum: f687338a6f1c463b03232337652804f62f5ae197ae9517a76cf6543ec5a3e358e41f26da0e4fc1afe4871c4a96eec3e3c440fb4ddb616cdc336b42ca203adb29 + checksum: 58c4fa45a78fcec75c78182a4b266395905957633654eb0311c5f9c30ac15c179ea2287ab1af034e46c2db7bb0589ef0000ee64c1de8f568a0aad29eaadb100c languageName: node linkType: hard From b33c52c8f704a23882cef3eb3a1a10e7ef1c2e69 Mon Sep 17 00:00:00 2001 From: Jasper Boeijenga Date: Thu, 7 Dec 2023 10:10:00 +0100 Subject: [PATCH 110/275] Generate new API documentation Signed-off-by: Jasper Boeijenga --- plugins/explore/api-report.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/explore/api-report.md b/plugins/explore/api-report.md index d32a133685..532b853671 100644 --- a/plugins/explore/api-report.md +++ b/plugins/explore/api-report.md @@ -8,6 +8,7 @@ import { ApiRef } from '@backstage/core-plugin-api'; import { BackstagePlugin } from '@backstage/core-plugin-api'; import { default as default_2 } from 'react'; +import { DependencyGraphTypes } from '@backstage/core-components'; import { DiscoveryApi } from '@backstage/core-plugin-api'; import { DomainEntity } from '@backstage/catalog-model'; import { ExploreToolsConfig } from '@backstage/plugin-explore-react'; @@ -110,6 +111,7 @@ export const exploreRouteRef: RouteRef; // @public (undocumented) export const GroupsExplorerContent: (props: { title?: string | undefined; + direction?: DependencyGraphTypes.Direction | undefined; }) => JSX_2.Element; // @public (undocumented) From 4befe4af742c86dcdea006e1a040a0ca3b6d5877 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 7 Dec 2023 10:20:28 +0100 Subject: [PATCH 111/275] docs/frontend-system: add naming pattern docs Signed-off-by: Patrik Oldsberg --- .../architecture/08-naming-patterns.md | 139 ++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 docs/frontend-system/architecture/08-naming-patterns.md diff --git a/docs/frontend-system/architecture/08-naming-patterns.md b/docs/frontend-system/architecture/08-naming-patterns.md new file mode 100644 index 0000000000..90d338d07d --- /dev/null +++ b/docs/frontend-system/architecture/08-naming-patterns.md @@ -0,0 +1,139 @@ +--- +id: naming-patterns +title: Frontend System Naming Patterns +sidebar_label: Naming Patterns +# prettier-ignore +description: Naming patterns in the frontend system +--- + +> **NOTE: The new frontend system is in a highly experimental phase** + +These are the naming patterns to adhere to within the frontend system. They help us keep exports and IDs consistent across packages and make it easier to understand the usage and intent of exports and IDs. + +As a rule, all names should be camel case, with the exceptions of plugin and extension IDs, which should use kebab case. + +### Plugins + +| Description | Pattern | Examples | +| ----------- | ------------ | ------------------------------------- | +| ID | `''` | `'catalog'`, `'user-settings'` | +| Symbol | `Plugin` | `catalogPlugin`, `userSettingsPlugin` | + +Example: + +```ts +export const userSettingsPlugin = createPlugin({ + id: 'user-settings', + ... +}) +``` + +Note that while we use this naming pattern for the plugin instance this is only for internal usage within the package. Plugins are always exported as the default export of the plugin package. + +### Extensions + +| Description | Pattern | Examples | +| ----------- | ------------------------------- | ------------------------------------------------------------------- | +| Kind | `` | `Page`, `EntityCard`, `SearchResultListItem` | +| Creator | `createExtension` | `createPageExtension`, `createEntityCardExtension` | +| ID | `[:][/]` | `'core.nav'`, `'page:user-settings'`, `'entity-card:catalog/about'` | +| Symbol | `[][]` | `coreNav`, `userSettingsPage`, `catalogAboutEntityCard` | + +When you create a new extension you never provide the ID directly. Instead, you indirectly or directly provide that kind, namespace, and name parts that make up the ID. The kind is always provided by the extension creator used to create the extension, the only exception is if you use `createExtension` directly. Any extension that is provided by a plugin will by default have its namespace set to the plugin ID, so you generally only need to provide an explicit namespace if you want to override an existing extension. The name is also optional, and primarily used to distinguish between multiple extensions of the same kind and namespace. If a plugin doesn't need to distinguish between different extensions of the same kind, the name can be omitted. + +Example: + +```ts +// This is an extension creator that is used to create an extension of the 'page' kind. +export function createPageExtension(options) { + return createExtension({ + kind: 'page', // Kinds are kebab-case + // ...options + }); +} + +// The namespace is inferred from the plugin ID, in this case 'catalog' +// The final ID for this extension will be 'page:catalog/entity' +const catalogEntityPage = createPageExtension({ + name: 'entity', + // ... +}); + +// The name is omitted, because the catalog plugin only provides a single extension of this kind +// The final ID for this extension will be 'search-result-list-item:catalog' +const catalogSearchResultListItem = createSearchResultListItemExtension({ + // ... +}); + +// Note that the extensions themselves are not exported, only the plugin instance +export const catalogPlugin = createPlugin({ + id: 'catalog', + extensions: [catalogEntityPage, catalogSearchResultListItem /* ... */], +}); +``` + +### Extension Data + +| Description | Pattern | Examples | +| -------------------- | ------------------------------------- | ----------------------------------------------------------------------------- | +| Interface | `ExtensionData` | `SearchResultItemExtensionData` | +| Standalone Reference | `ExtensionDataRef` | `searchResultItemExtensionDataRef` | +| Standalone ID | `.` | `'search.search-result-item'` | +| Grouped Reference | `ExtensionData.` | `coreExtensionData.reactElement`, `catalogFilterExtensionData.functionFilter` | +| Grouped ID | `.` | `'core.react-element'`, `'catalog-filter.function-filter'` | +| Creator Reference | `createExtension.DataRef` | `createGraphiQLEndpointExtension.endpointDataRef` | +| Creator ID | `..` | `'graphiql.graphiql-endpoint.endpoint'` | + +Extension data references can be defined in a couple of different ways, depending on the intended usage, all of which are covered below. + +#### Standalone Extension Data + +The most simple way of defining extension data is a standalone reference. This is useful when you want to export a single reference that isn't closely tied to a specific kind of extension. Because this creates an extra export for each reference, the two other ways of defining extension data are preferred when possible. + +```ts +// A separate named type declaration is only needed for bespoke complex extension data types +export interface SearchResultItemExtensionData { + /* ... */ +} + +export const searchResultItemExtensionDataRef = + createExtensionDataRef( + 'search.search-result-item', + ); +``` + +#### Grouped Extension Data + +This way of defining extension data is similar to the standalone way, but it used when you want to export multiple pieces of grouped extension data for general use. This avoids separate exports and help make related extension data references easier to discover. The name of the group should generally by the same as the namespace of the exporting package, typically the plugin ID. If the group needs to be more specific it should be prefixed with the namespace. + +```ts +export const coreExtensionData = { + reactElement: createExtensionDataRef('core.react-element'), + routePath: createExtensionDataRef('core.route-path'), +}; +``` + +#### Extension Creator Extension Data + +This is a convenient way of defining extension data when that data is only meant to be produced by a specific extension creator. It avoids additional exports and clearly signals that this piece of data belongs to this particular kind of extension. + +```ts +export function createGraphiQLEndpointExtension(options) { + /* ... */ +} + +// Use a TypeScript namespace to merge the extension data references with the extension creator +export namespace createGraphiQLEndpointExtension { + export const endpointDataRef = createExtensionDataRef( + 'graphiql.graphiql-endpoint.endpoint', + ); +} +``` + +### Extension Inputs + +Extension inputs do not have naming patterns for all kind of inputs, but there are some specific use-cases where we encourage to use a recognizable input name. + +| Name | Description | +| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `children` | An extension input that accepts `coreExtensionData.reactElement` data and nothing else, used in a way that is equivalent of the `children` property in React. | From 76e46539774bdd830b29f54ede9b0fd33f708b22 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 7 Dec 2023 09:43:13 +0000 Subject: [PATCH 112/275] fix(deps): update dependency html-webpack-plugin to v5.5.4 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 63297048a7..fd0650d51c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -29239,8 +29239,8 @@ __metadata: linkType: hard "html-webpack-plugin@npm:^5.3.1": - version: 5.5.3 - resolution: "html-webpack-plugin@npm:5.5.3" + version: 5.5.4 + resolution: "html-webpack-plugin@npm:5.5.4" dependencies: "@types/html-minifier-terser": ^6.0.0 html-minifier-terser: ^6.0.2 @@ -29249,7 +29249,7 @@ __metadata: tapable: ^2.0.0 peerDependencies: webpack: ^5.20.0 - checksum: ccf685195739c372ad641bbd0c9100a847904f34eedc7aff3ece7856cd6c78fd3746d2d615af1bb71e5727993fe711b89e9b744f033ed3fde646540bf5d5e954 + checksum: b49befb73d67a3716fd0e6f7776b108d2b0b7050fb8221f05cd114cbae13c03150a13b7cdf5e76170be040ce7936a1cf76f7a4bfd9ebe1552b72d7889a74c374 languageName: node linkType: hard From 0ec8703c30de219bddc8e7fe526274aeb0aeb8da Mon Sep 17 00:00:00 2001 From: Frida Jacobsson Date: Thu, 7 Dec 2023 14:52:17 +0100 Subject: [PATCH 113/275] Added the Readme plugin to the Directory. The new Readme plugin has been added to the plugin Directory at backstage.io. Signed-off-by: Frida Jacobsson --- microsite/data/plugins/readme.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 microsite/data/plugins/readme.yaml diff --git a/microsite/data/plugins/readme.yaml b/microsite/data/plugins/readme.yaml new file mode 100644 index 0000000000..695e358e00 --- /dev/null +++ b/microsite/data/plugins/readme.yaml @@ -0,0 +1,11 @@ +--- +title: Readme +author: AxisCommunications +authorUrl: https://github.com/AxisCommunications +category: Metadata +description: The Readme-plugin enables easy access and viewing of the README.md file in your entity overview. +documentation: https://github.com/AxisCommunications/backstage-plugins/blob/main/plugins/readme/README.md +iconUrl: https://github.com/AxisCommunications/backstage-plugins/blob/main/plugins/readme/media/readme.png +npmPackageName: '@axis-backstage/plugin-readme' +addedDate: '2023-12-07' + From 5f0f9ea4858617882b2fdcc9ff286ccea550de1a Mon Sep 17 00:00:00 2001 From: Frida Jacobsson Date: Thu, 7 Dec 2023 14:55:01 +0100 Subject: [PATCH 114/275] Update and rename jira-dashboard to jira-dashboard.yaml In the last PR, the filename extension .yaml was missing. It has been added and the "addedDate" updated. Signed-off-by: Frida Jacobsson --- microsite/data/plugins/{jira-dashboard => jira-dashboard.yaml} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename microsite/data/plugins/{jira-dashboard => jira-dashboard.yaml} (96%) diff --git a/microsite/data/plugins/jira-dashboard b/microsite/data/plugins/jira-dashboard.yaml similarity index 96% rename from microsite/data/plugins/jira-dashboard rename to microsite/data/plugins/jira-dashboard.yaml index 2e67deb4a9..24fb01fecf 100644 --- a/microsite/data/plugins/jira-dashboard +++ b/microsite/data/plugins/jira-dashboard.yaml @@ -7,4 +7,4 @@ description: Allows you to fetch and display Jira issues for your entity. You ge documentation: https://github.com/AxisCommunications/backstage-plugins/blob/main/plugins/jira-dashboard/README.md iconUrl: https://github.com/AxisCommunications/backstage-plugins/blob/main/plugins/jira-dashboard/media/jira-logo.png npmPackageName: '@axis-backstage/plugin-jira-dashboard' -addedDate: '2023-11-29' +addedDate: '2023-12-07' From c8908d4b62721446ee8a4d39ef1462adfdadd377 Mon Sep 17 00:00:00 2001 From: solimant Date: Thu, 7 Dec 2023 15:53:59 +0000 Subject: [PATCH 115/275] Use new option from RJSF 5.15 Signed-off-by: solimant --- .changeset/tiny-coins-raise.md | 7 +++++++ .../components/CustomHomepage/WidgetSettingsOverlay.tsx | 3 +++ .../src/next/components/Stepper/Stepper.tsx | 3 +++ .../src/legacy/MultistepJsonForm/MultistepJsonForm.tsx | 3 +++ .../src/legacy/TemplateEditorPage/CustomFieldExplorer.tsx | 3 +++ .../src/next/TemplateEditorPage/CustomFieldExplorer.tsx | 3 +++ 6 files changed, 22 insertions(+) create mode 100644 .changeset/tiny-coins-raise.md diff --git a/.changeset/tiny-coins-raise.md b/.changeset/tiny-coins-raise.md new file mode 100644 index 0000000000..cdb501fb78 --- /dev/null +++ b/.changeset/tiny-coins-raise.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-scaffolder-react': patch +'@backstage/plugin-scaffolder': patch +'@backstage/plugin-home': patch +--- + +Use new option from RJSF 5.15 diff --git a/plugins/home/src/components/CustomHomepage/WidgetSettingsOverlay.tsx b/plugins/home/src/components/CustomHomepage/WidgetSettingsOverlay.tsx index aec4b3dcf2..735720ac13 100644 --- a/plugins/home/src/components/CustomHomepage/WidgetSettingsOverlay.tsx +++ b/plugins/home/src/components/CustomHomepage/WidgetSettingsOverlay.tsx @@ -91,6 +91,9 @@ export const WidgetSettingsOverlay = (props: WidgetSettingsOverlayProps) => { setSettingsDialogOpen(false); } }} + experimental_defaultFormStateBehavior={{ + allOf: 'populateDefaults', + }} /> diff --git a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx index a0b06c0e69..5b41163ae4 100644 --- a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx +++ b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx @@ -230,6 +230,9 @@ export const Stepper = (stepperProps: StepperProps) => { fields={fields} showErrorList={false} onChange={handleChange} + experimental_defaultFormStateBehavior={{ + allOf: 'populateDefaults', + }} {...(props.formProps ?? {})} >
diff --git a/plugins/scaffolder/src/legacy/MultistepJsonForm/MultistepJsonForm.tsx b/plugins/scaffolder/src/legacy/MultistepJsonForm/MultistepJsonForm.tsx index 312522bc88..68b25d97d2 100644 --- a/plugins/scaffolder/src/legacy/MultistepJsonForm/MultistepJsonForm.tsx +++ b/plugins/scaffolder/src/legacy/MultistepJsonForm/MultistepJsonForm.tsx @@ -192,6 +192,9 @@ export const MultistepJsonForm = (props: MultistepJsonFormProps) => { onSubmit={(e: IChangeEvent) => { if (e.errors.length === 0) handleNext(); }} + experimental_defaultFormStateBehavior={{ + allOf: 'populateDefaults', + }} {...formProps} {...transformSchemaToProps(schema, layouts)} > diff --git a/plugins/scaffolder/src/legacy/TemplateEditorPage/CustomFieldExplorer.tsx b/plugins/scaffolder/src/legacy/TemplateEditorPage/CustomFieldExplorer.tsx index 9107ac67eb..def3bf1796 100644 --- a/plugins/scaffolder/src/legacy/TemplateEditorPage/CustomFieldExplorer.tsx +++ b/plugins/scaffolder/src/legacy/TemplateEditorPage/CustomFieldExplorer.tsx @@ -161,6 +161,9 @@ export const CustomFieldExplorer = ({ onSubmit={e => handleFieldConfigChange(e.formData)} validator={validator} schema={selectedField.schema?.uiOptions || {}} + experimental_defaultFormStateBehavior={{ + allOf: 'populateDefaults', + }} > +
+ ); + }; + + return { + element: , + }; + }, + }); + + const tester = createExtensionTester(indexPageExtension); + + // Overriding the analytics api extension + tester.add(analyticsApiOverride); + + tester.render(); + + fireEvent.click(await screen.findByRole('button', { name: 'See details' })); + + await waitFor(() => + expect(analyticsApiMock.getEvents()[1]).toMatchObject({ + action: 'click', + subject: 'See details', + }), ); }); }); diff --git a/packages/frontend-test-utils/src/app/createExtensionTester.ts b/packages/frontend-test-utils/src/app/createExtensionTester.ts index 257a47439c..18c3c84ec9 100644 --- a/packages/frontend-test-utils/src/app/createExtensionTester.ts +++ b/packages/frontend-test-utils/src/app/createExtensionTester.ts @@ -17,6 +17,8 @@ import { createSpecializedApp } from '@backstage/frontend-app-api'; import { ExtensionDefinition, + coreExtensionData, + createExtension, createExtensionOverrides, } from '@backstage/frontend-plugin-api'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports @@ -33,13 +35,27 @@ export class ExtensionTester { options?: { config?: TConfig }, ): ExtensionTester { const tester = new ExtensionTester(); - tester.add(subject, options); + const { output, factory, ...rest } = subject; + // attaching to core/routes to render as index route + const extension = createExtension({ + ...rest, + attachTo: { id: 'core/routes', input: 'routes' }, + output: { + ...output, + path: coreExtensionData.routePath, + }, + factory: params => ({ + ...factory(params), + path: '/', + }), + }); + tester.add(extension, options); return tester; } readonly #extensions = new Array<{ id: string; - extension: ExtensionDefinition; + definition: ExtensionDefinition; config?: JsonValue; }>(); @@ -47,13 +63,19 @@ export class ExtensionTester { extension: ExtensionDefinition, options?: { config?: TConfig }, ): ExtensionTester { - const withNamespace = { + const { name, namespace } = extension; + + const definition = { ...extension, - name: !extension.namespace && !extension.name ? 'test' : extension.name, + // setting name "test" as fallback + name: !namespace && !name ? 'test' : name, }; + + const { id } = resolveExtensionDefinition(definition); + this.#extensions.push({ - id: resolveExtensionDefinition(withNamespace).id, - extension: withNamespace, + id, + definition, config: options?.config as JsonValue, }); @@ -71,27 +93,17 @@ export class ExtensionTester { } const extensionsConfig: JsonArray = [ - ...rest.map(entry => ({ - [entry.id]: { - config: entry.config, + ...rest.map(extension => ({ + [extension.id]: { + config: extension.config, }, })), { [subject.id]: { - attachTo: { id: 'core/router', input: 'children' }, config: subject.config, disabled: false, }, }, - { - 'core/layout': false, - }, - { - 'core/nav': false, - }, - { - 'core/routes': false, - }, ]; const finalConfig = { @@ -105,7 +117,7 @@ export class ExtensionTester { const app = createSpecializedApp({ features: [ createExtensionOverrides({ - extensions: this.#extensions.map(entry => entry.extension), + extensions: this.#extensions.map(extension => extension.definition), }), ], config: new MockConfigApi(finalConfig), diff --git a/packages/frontend-test-utils/src/app/renderInTestApp.test.tsx b/packages/frontend-test-utils/src/app/renderInTestApp.test.tsx index e13d1157ef..d51f66010c 100644 --- a/packages/frontend-test-utils/src/app/renderInTestApp.test.tsx +++ b/packages/frontend-test-utils/src/app/renderInTestApp.test.tsx @@ -14,14 +14,53 @@ * limitations under the License. */ -import React from 'react'; -import { screen } from '@testing-library/react'; +import React, { useCallback } from 'react'; +import { screen, fireEvent } from '@testing-library/react'; +import { + MockAnalyticsApi, + TestApiProvider, +} from '@backstage/frontend-test-utils'; +import { analyticsApiRef, useAnalytics } from '@backstage/frontend-plugin-api'; import { renderInTestApp } from './renderInTestApp'; describe('renderInTestApp', () => { it('should render the given component in a page', async () => { - const Component = () =>
Test
; - renderInTestApp(); - expect(screen.getByText('Test')).toBeInTheDocument(); + const IndexPage = () =>
Index Page
; + renderInTestApp(); + expect(screen.getByText('Index Page')).toBeInTheDocument(); + }); + + it('should works with apis provider', async () => { + const IndexPage = () => { + const analyticsApi = useAnalytics(); + const handleClick = useCallback(() => { + analyticsApi.captureEvent('click', 'See details'); + }, [analyticsApi]); + return ( +
+ ); + }; + + const analyticsApiMock = new MockAnalyticsApi(); + + renderInTestApp( + + + , + ); + + fireEvent.click(screen.getByRole('link', { name: 'See details' })); + + const events = analyticsApiMock.getEvents(); + + expect(events[1]).toMatchObject({ + action: 'click', + subject: 'See details', + }); }); }); diff --git a/yarn.lock b/yarn.lock index 8a7e8a1dac..8689a6ad0d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4227,11 +4227,13 @@ __metadata: resolution: "@backstage/frontend-test-utils@workspace:packages/frontend-test-utils" dependencies: "@backstage/cli": "workspace:^" + "@backstage/core-components": "workspace:^" "@backstage/frontend-app-api": "workspace:^" "@backstage/frontend-plugin-api": "workspace:^" "@backstage/test-utils": "workspace:^" "@backstage/types": "workspace:^" "@testing-library/jest-dom": ^6.0.0 + "@types/react": "*" peerDependencies: "@testing-library/react": ^12.1.3 || ^13.0.0 || ^14.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 From bef798ae725c84be3363c859dd085779df63b288 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Mon, 11 Dec 2023 10:10:14 +0100 Subject: [PATCH 174/275] fix(frontend-app-api): fix apis overriding Signed-off-by: Camila Belo --- .../frontend-app-api/src/wiring/createApp.tsx | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/frontend-app-api/src/wiring/createApp.tsx b/packages/frontend-app-api/src/wiring/createApp.tsx index 67b8494953..a88c03b188 100644 --- a/packages/frontend-app-api/src/wiring/createApp.tsx +++ b/packages/frontend-app-api/src/wiring/createApp.tsx @@ -388,7 +388,14 @@ function createApiHolder( (x): x is typeof createTranslationExtension.translationDataRef.T => !!x, ) ?? []; + const apis = new Map(); + + // removing duplicates by id, overriding the default one with the plugin one for (const factory of [...defaultApis, ...pluginApis]) { + apis.set(factory.api.id, factory); + } + + for (const factory of apis.values()) { factoryRegistry.register('default', factory); } @@ -466,15 +473,6 @@ function createApiHolder( }), }); - // TODO: ship these as default extensions instead - for (const factory of defaultApis as AnyApiFactory[]) { - if (!factoryRegistry.register('app', factory)) { - throw new Error( - `Duplicate or forbidden API factory for ${factory.api} in app`, - ); - } - } - ApiResolver.validateFactories(factoryRegistry, factoryRegistry.getAllApis()); return new ApiResolver(factoryRegistry); From 7e4b0db5d169806027653c870948fe09fa18fbfb Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Sat, 9 Dec 2023 12:29:43 +0100 Subject: [PATCH 175/275] chore: add changeset file Signed-off-by: Camila Belo --- .changeset/cool-fans-wash.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/cool-fans-wash.md diff --git a/.changeset/cool-fans-wash.md b/.changeset/cool-fans-wash.md new file mode 100644 index 0000000000..8154298047 --- /dev/null +++ b/.changeset/cool-fans-wash.md @@ -0,0 +1,5 @@ +--- +'@backstage/frontend-test-utils': patch +--- + +Accepts rendering more than a route in the test app. From 66ce9f6d1eb5b2d7ffd75835756ddd8dd1c64524 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Wed, 13 Dec 2023 16:41:57 +0100 Subject: [PATCH 176/275] refactor(frontend-app-api): converting default apis into extensions Signed-off-by: Camila Belo --- packages/frontend-app-api/src/wiring/createApp.tsx | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/packages/frontend-app-api/src/wiring/createApp.tsx b/packages/frontend-app-api/src/wiring/createApp.tsx index a88c03b188..4dc9eda4a0 100644 --- a/packages/frontend-app-api/src/wiring/createApp.tsx +++ b/packages/frontend-app-api/src/wiring/createApp.tsx @@ -103,6 +103,8 @@ import { toInternalBackstagePlugin } from '../../../frontend-plugin-api/src/wiri import { toInternalExtensionOverrides } from '../../../frontend-plugin-api/src/wiring/createExtensionOverrides'; import { DefaultComponentsApi } from '../apis/implementations/ComponentsApi'; +const DefaultApis = defaultApis.map(factory => createApiExtension({ factory })); + export const builtinExtensions = [ Core, CoreRouter, @@ -114,6 +116,7 @@ export const builtinExtensions = [ DefaultNotFoundErrorPageComponent, LightTheme, DarkTheme, + ...DefaultApis, ].map(def => resolveExtensionDefinition(def)); /** @public */ @@ -388,14 +391,7 @@ function createApiHolder( (x): x is typeof createTranslationExtension.translationDataRef.T => !!x, ) ?? []; - const apis = new Map(); - - // removing duplicates by id, overriding the default one with the plugin one - for (const factory of [...defaultApis, ...pluginApis]) { - apis.set(factory.api.id, factory); - } - - for (const factory of apis.values()) { + for (const factory of pluginApis) { factoryRegistry.register('default', factory); } From 58141224d3a553b6c0a5f51955ce209c288b8c7d Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 13 Dec 2023 17:39:18 +0100 Subject: [PATCH 177/275] plugins: update all other plugins to fit new frontend system naming patterns Signed-off-by: Patrik Oldsberg --- .changeset/polite-rocks-kiss.md | 15 +++++++++ plugins/adr/api-report-alpha.md | 2 +- plugins/adr/src/alpha.tsx | 4 +-- plugins/catalog-import/src/alpha.tsx | 6 ++-- plugins/explore/api-report-alpha.md | 2 +- plugins/explore/src/alpha.tsx | 17 +++++----- plugins/graphiql/api-report-alpha.md | 8 ++--- plugins/graphiql/src/alpha.tsx | 42 +++++++++++++----------- plugins/home/src/alpha.tsx | 4 +-- plugins/search-react/api-report-alpha.md | 21 +++++++----- plugins/search-react/src/alpha.test.tsx | 3 +- plugins/search-react/src/alpha.tsx | 16 +++++---- plugins/search/api-report-alpha.md | 6 ++-- plugins/search/src/alpha.tsx | 12 +++---- plugins/stack-overflow/src/alpha.tsx | 6 ++-- plugins/tech-radar/api-report-alpha.md | 4 +-- plugins/tech-radar/src/alpha.test.tsx | 4 +-- plugins/tech-radar/src/alpha.tsx | 6 ++-- plugins/techdocs/api-report-alpha.md | 2 +- plugins/techdocs/src/alpha.tsx | 28 ++++++++-------- plugins/user-settings/src/alpha.tsx | 4 +-- 21 files changed, 116 insertions(+), 96 deletions(-) create mode 100644 .changeset/polite-rocks-kiss.md diff --git a/.changeset/polite-rocks-kiss.md b/.changeset/polite-rocks-kiss.md new file mode 100644 index 0000000000..8382550620 --- /dev/null +++ b/.changeset/polite-rocks-kiss.md @@ -0,0 +1,15 @@ +--- +'@backstage/plugin-catalog-import': patch +'@backstage/plugin-stack-overflow': patch +'@backstage/plugin-user-settings': patch +'@backstage/plugin-search-react': patch +'@backstage/plugin-tech-radar': patch +'@backstage/plugin-graphiql': patch +'@backstage/plugin-techdocs': patch +'@backstage/plugin-explore': patch +'@backstage/plugin-search': patch +'@backstage/plugin-home': patch +'@backstage/plugin-adr': patch +--- + +Updated `/alpha` exports to fit new naming patterns. diff --git a/plugins/adr/api-report-alpha.md b/plugins/adr/api-report-alpha.md index 4c9ac1d17e..bfa27a6d4f 100644 --- a/plugins/adr/api-report-alpha.md +++ b/plugins/adr/api-report-alpha.md @@ -8,7 +8,7 @@ import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; import { TranslationRef } from '@backstage/core-plugin-api/alpha'; // @alpha (undocumented) -export const AdrSearchResultListItemExtension: ExtensionDefinition<{ +export const adrSearchResultListItemExtension: ExtensionDefinition<{ lineClamp: number; noTrack: boolean; }>; diff --git a/plugins/adr/src/alpha.tsx b/plugins/adr/src/alpha.tsx index ea4d32e0da..4abba11fcf 100644 --- a/plugins/adr/src/alpha.tsx +++ b/plugins/adr/src/alpha.tsx @@ -29,7 +29,7 @@ function isAdrDocument(result: any): result is AdrDocument { } /** @alpha */ -export const AdrSearchResultListItemExtension = +export const adrSearchResultListItemExtension = createSearchResultListItemExtension({ configSchema: createSchemaFromZod(z => z.object({ @@ -53,5 +53,5 @@ export const AdrSearchResultListItemExtension = /** @alpha */ export default createPlugin({ id: 'adr', - extensions: [AdrSearchResultListItemExtension], + extensions: [adrSearchResultListItemExtension], }); diff --git a/plugins/catalog-import/src/alpha.tsx b/plugins/catalog-import/src/alpha.tsx index 858e4fa91b..304ee3f272 100644 --- a/plugins/catalog-import/src/alpha.tsx +++ b/plugins/catalog-import/src/alpha.tsx @@ -40,7 +40,7 @@ import { catalogApiRef } from '@backstage/plugin-catalog-react'; // TODO: It's currently possible to override the import page with a custom one. We need to decide // whether this type of override is typically done with an input or by overriding the entire extension. -const CatalogImportPageExtension = createPageExtension({ +const catalogImportPage = createPageExtension({ defaultPath: '/catalog-import', routeRef: convertLegacyRouteRef(rootRouteRef), loader: () => @@ -49,7 +49,7 @@ const CatalogImportPageExtension = createPageExtension({ ), }); -const CatalogImportService = createApiExtension({ +const catalogImportApi = createApiExtension({ factory: createApiFactory({ api: catalogImportApiRef, deps: { @@ -82,7 +82,7 @@ const CatalogImportService = createApiExtension({ /** @alpha */ export default createPlugin({ id: 'catalog-import', - extensions: [CatalogImportService, CatalogImportPageExtension], + extensions: [catalogImportApi, catalogImportPage], routes: { importPage: convertLegacyRouteRef(rootRouteRef), }, diff --git a/plugins/explore/api-report-alpha.md b/plugins/explore/api-report-alpha.md index 4d1afa89bf..7956cb8546 100644 --- a/plugins/explore/api-report-alpha.md +++ b/plugins/explore/api-report-alpha.md @@ -11,7 +11,7 @@ const _default: BackstagePlugin<{}, {}>; export default _default; // @alpha (undocumented) -export const ExploreSearchResultListItemExtension: ExtensionDefinition<{ +export const exploreSearchResultListItem: ExtensionDefinition<{ noTrack?: boolean | undefined; }>; diff --git a/plugins/explore/src/alpha.tsx b/plugins/explore/src/alpha.tsx index f06379c84b..3ee25f1bdb 100644 --- a/plugins/explore/src/alpha.tsx +++ b/plugins/explore/src/alpha.tsx @@ -18,17 +18,16 @@ import { createPlugin } from '@backstage/frontend-plugin-api'; import { createSearchResultListItemExtension } from '@backstage/plugin-search-react/alpha'; /** @alpha */ -export const ExploreSearchResultListItemExtension = - createSearchResultListItemExtension({ - predicate: result => result.type === 'tools', - component: () => - import('./components/ToolSearchResultListItem').then( - m => m.ToolSearchResultListItem, - ), - }); +export const exploreSearchResultListItem = createSearchResultListItemExtension({ + predicate: result => result.type === 'tools', + component: () => + import('./components/ToolSearchResultListItem').then( + m => m.ToolSearchResultListItem, + ), +}); /** @alpha */ export default createPlugin({ id: 'explore', - extensions: [ExploreSearchResultListItemExtension], + extensions: [exploreSearchResultListItem], }); diff --git a/plugins/graphiql/api-report-alpha.md b/plugins/graphiql/api-report-alpha.md index c5895067df..e642425463 100644 --- a/plugins/graphiql/api-report-alpha.md +++ b/plugins/graphiql/api-report-alpha.md @@ -33,13 +33,13 @@ export default _default; export const graphiqlBrowseApi: ExtensionDefinition<{}>; // @alpha (undocumented) -export const GraphiqlPage: ExtensionDefinition<{ - path: string; +export const graphiqlNavItem: ExtensionDefinition<{ + title: string; }>; // @alpha (undocumented) -export const graphiqlPageSidebarItem: ExtensionDefinition<{ - title: string; +export const graphiqlPage: ExtensionDefinition<{ + path: string; }>; // (No @packageDocumentation comment for this package) diff --git a/plugins/graphiql/src/alpha.tsx b/plugins/graphiql/src/alpha.tsx index 2fbd9235ac..fdd343020d 100644 --- a/plugins/graphiql/src/alpha.tsx +++ b/plugins/graphiql/src/alpha.tsx @@ -40,7 +40,7 @@ import { } from '@backstage/core-compat-api'; /** @alpha */ -export const GraphiqlPage = createPageExtension({ +export const graphiqlPage = createPageExtension({ defaultPath: '/graphiql', routeRef: convertLegacyRouteRef(graphiQLRouteRef), loader: () => @@ -48,7 +48,7 @@ export const GraphiqlPage = createPageExtension({ }); /** @alpha */ -export const graphiqlPageSidebarItem = createNavItemExtension({ +export const graphiqlNavItem = createNavItemExtension({ title: 'GraphiQL', icon: GraphiQLIcon as IconComponent, routeRef: convertLegacyRouteRef(graphiQLRouteRef), @@ -56,7 +56,7 @@ export const graphiqlPageSidebarItem = createNavItemExtension({ /** @internal */ const endpointDataRef = createExtensionDataRef( - 'plugin.graphiql.endpoint', + 'graphiql.graphiql-endpoint', ); /** @alpha */ @@ -102,29 +102,31 @@ export function createGraphiQLEndpointExtension(options: { } /** @alpha */ -const gitlabGraphiQLBrowseExtension = createGraphiQLEndpointExtension({ - name: 'gitlab', - disabled: true, - configSchema: createSchemaFromZod(z => - z - .object({ - id: z.string().default('gitlab'), - title: z.string().default('GitLab'), - url: z.string().default('https://gitlab.com/api/graphql'), - }) - .default({}), - ), - factory: ({ config }) => ({ endpoint: GraphQLEndpoints.create(config) }), -}); +const graphiqlGitlabGraphiQLEndpointExtension = createGraphiQLEndpointExtension( + { + name: 'gitlab', + disabled: true, + configSchema: createSchemaFromZod(z => + z + .object({ + id: z.string().default('gitlab'), + title: z.string().default('GitLab'), + url: z.string().default('https://gitlab.com/api/graphql'), + }) + .default({}), + ), + factory: ({ config }) => ({ endpoint: GraphQLEndpoints.create(config) }), + }, +); /** @alpha */ export default createPlugin({ id: 'graphiql', extensions: [ - GraphiqlPage, + graphiqlPage, graphiqlBrowseApi, - gitlabGraphiQLBrowseExtension, - graphiqlPageSidebarItem, + graphiqlGitlabGraphiQLEndpointExtension, + graphiqlNavItem, ], routes: { root: convertLegacyRouteRef(graphiQLRouteRef), diff --git a/plugins/home/src/alpha.tsx b/plugins/home/src/alpha.tsx index 631f4293be..e9ff26c9e1 100644 --- a/plugins/home/src/alpha.tsx +++ b/plugins/home/src/alpha.tsx @@ -33,7 +33,7 @@ const rootRouteRef = createRouteRef(); */ export const titleExtensionDataRef = createExtensionDataRef('title'); -const HomepageCompositionRootExtension = createPageExtension({ +const homePage = createPageExtension({ defaultPath: '/home', routeRef: rootRouteRef, inputs: { @@ -65,5 +65,5 @@ const HomepageCompositionRootExtension = createPageExtension({ */ export default createPlugin({ id: 'home', - extensions: [HomepageCompositionRootExtension], + extensions: [homePage], }); diff --git a/plugins/search-react/api-report-alpha.md b/plugins/search-react/api-report-alpha.md index 285f1232c2..b0edd42646 100644 --- a/plugins/search-react/api-report-alpha.md +++ b/plugins/search-react/api-report-alpha.md @@ -27,6 +27,18 @@ export function createSearchResultListItemExtension< options: SearchResultItemExtensionOptions, ): ExtensionDefinition; +// @alpha (undocumented) +export namespace createSearchResultListItemExtension { + const // (undocumented) + itemDataRef: ConfigurableExtensionDataRef< + { + predicate?: SearchResultItemExtensionPredicate | undefined; + component: SearchResultItemExtensionComponent; + }, + {} + >; +} + // @alpha (undocumented) export type SearchResultItemExtensionComponent = < P extends BaseSearchResultListItemProps, @@ -34,15 +46,6 @@ export type SearchResultItemExtensionComponent = < props: P, ) => JSX.Element | null; -// @alpha (undocumented) -export const searchResultItemExtensionData: ConfigurableExtensionDataRef< - { - predicate?: SearchResultItemExtensionPredicate | undefined; - component: SearchResultItemExtensionComponent; - }, - {} ->; - // @alpha (undocumented) export type SearchResultItemExtensionOptions< TConfig extends { diff --git a/plugins/search-react/src/alpha.test.tsx b/plugins/search-react/src/alpha.test.tsx index 3b05c61eb2..6d77b5af97 100644 --- a/plugins/search-react/src/alpha.test.tsx +++ b/plugins/search-react/src/alpha.test.tsx @@ -26,7 +26,6 @@ import React from 'react'; import { BaseSearchResultListItemProps, createSearchResultListItemExtension, - searchResultItemExtensionData as searchResultListItemExtensionData, } from './alpha'; describe('createSearchResultListItemExtension', () => { @@ -76,7 +75,7 @@ describe('createSearchResultListItemExtension', () => { defaultPath: '/', inputs: { items: createExtensionInput({ - item: searchResultListItemExtensionData, + item: createSearchResultListItemExtension.itemDataRef, }), }, loader: async ({ inputs }) => { diff --git a/plugins/search-react/src/alpha.tsx b/plugins/search-react/src/alpha.tsx index c733e2ee9f..e075d9bfb8 100644 --- a/plugins/search-react/src/alpha.tsx +++ b/plugins/search-react/src/alpha.tsx @@ -47,12 +47,6 @@ export type SearchResultItemExtensionPredicate = ( result: SearchResult, ) => boolean; -/** @alpha */ -export const searchResultItemExtensionData = createExtensionDataRef<{ - predicate?: SearchResultItemExtensionPredicate; - component: SearchResultItemExtensionComponent; -}>('plugin.search.result.item.data'); - /** @alpha */ export type SearchResultItemExtensionOptions< TConfig extends { noTrack?: boolean }, @@ -109,7 +103,7 @@ export function createSearchResultListItemExtension< }, configSchema, output: { - item: searchResultItemExtensionData, + item: createSearchResultListItemExtension.itemDataRef, }, factory({ config, node }) { const ExtensionComponent = lazy(() => @@ -137,3 +131,11 @@ export function createSearchResultListItemExtension< }, }); } + +/** @alpha */ +export namespace createSearchResultListItemExtension { + export const itemDataRef = createExtensionDataRef<{ + predicate?: SearchResultItemExtensionPredicate; + component: SearchResultItemExtensionComponent; + }>('search.search-result-list-item.item'); +} diff --git a/plugins/search/api-report-alpha.md b/plugins/search/api-report-alpha.md index 533734f8e9..db2999ba25 100644 --- a/plugins/search/api-report-alpha.md +++ b/plugins/search/api-report-alpha.md @@ -17,15 +17,15 @@ const _default: BackstagePlugin< export default _default; // @alpha (undocumented) -export const SearchApi: ExtensionDefinition<{}>; +export const searchApi: ExtensionDefinition<{}>; // @alpha (undocumented) -export const SearchNavItem: ExtensionDefinition<{ +export const searchNavItem: ExtensionDefinition<{ title: string; }>; // @alpha (undocumented) -export const SearchPage: ExtensionDefinition<{ +export const searchPage: ExtensionDefinition<{ path: string; noTrack: boolean; }>; diff --git a/plugins/search/src/alpha.tsx b/plugins/search/src/alpha.tsx index 7899fb2ae1..a3a5023693 100644 --- a/plugins/search/src/alpha.tsx +++ b/plugins/search/src/alpha.tsx @@ -61,7 +61,7 @@ import { } from '@backstage/plugin-search-react'; import { SearchResult } from '@backstage/plugin-search-common'; import { searchApiRef } from '@backstage/plugin-search-react'; -import { searchResultItemExtensionData } from '@backstage/plugin-search-react/alpha'; +import { createSearchResultListItemExtension } from '@backstage/plugin-search-react/alpha'; import { rootRouteRef } from './plugin'; import { SearchClient } from './apis'; @@ -73,7 +73,7 @@ import { } from '@backstage/core-compat-api'; /** @alpha */ -export const SearchApi = createApiExtension({ +export const searchApi = createApiExtension({ factory: { api: searchApiRef, deps: { discoveryApi: discoveryApiRef, identityApi: identityApiRef }, @@ -100,7 +100,7 @@ const useSearchPageStyles = makeStyles((theme: Theme) => ({ })); /** @alpha */ -export const SearchPage = createPageExtension({ +export const searchPage = createPageExtension({ routeRef: convertLegacyRouteRef(rootRouteRef), configSchema: createSchemaFromZod(z => z.object({ @@ -110,7 +110,7 @@ export const SearchPage = createPageExtension({ ), inputs: { items: createExtensionInput({ - item: searchResultItemExtensionData, + item: createSearchResultListItemExtension.itemDataRef, }), }, loader: async ({ config, inputs }) => { @@ -238,7 +238,7 @@ export const SearchPage = createPageExtension({ }); /** @alpha */ -export const SearchNavItem = createNavItemExtension({ +export const searchNavItem = createNavItemExtension({ routeRef: convertLegacyRouteRef(rootRouteRef), title: 'Search', icon: SearchIcon, @@ -247,7 +247,7 @@ export const SearchNavItem = createNavItemExtension({ /** @alpha */ export default createPlugin({ id: 'search', - extensions: [SearchApi, SearchPage, SearchNavItem], + extensions: [searchApi, searchPage, searchNavItem], routes: { root: convertLegacyRouteRef(rootRouteRef), }, diff --git a/plugins/stack-overflow/src/alpha.tsx b/plugins/stack-overflow/src/alpha.tsx index f34c91f78b..689522b114 100644 --- a/plugins/stack-overflow/src/alpha.tsx +++ b/plugins/stack-overflow/src/alpha.tsx @@ -23,7 +23,7 @@ import { createSearchResultListItemExtension } from '@backstage/plugin-search-re import { StackOverflowClient, stackOverflowApiRef } from './api'; /** @alpha */ -const StackOverflowApi = createApiExtension({ +const stackOverflowApi = createApiExtension({ factory: createApiFactory({ api: stackOverflowApiRef, deps: { configApi: configApiRef }, @@ -32,7 +32,7 @@ const StackOverflowApi = createApiExtension({ }); /** @alpha */ -const StackOverflowSearchResultListItem = createSearchResultListItemExtension({ +const stackOverflowSearchResultListItem = createSearchResultListItemExtension({ predicate: result => result.type === 'stack-overflow', component: () => import('./search/StackOverflowSearchResultListItem').then( @@ -44,5 +44,5 @@ const StackOverflowSearchResultListItem = createSearchResultListItemExtension({ export default createPlugin({ id: 'stack-overflow', // TODO: Migrate homepage cards when the declarative homepage plugin supports them - extensions: [StackOverflowApi, StackOverflowSearchResultListItem], + extensions: [stackOverflowApi, stackOverflowSearchResultListItem], }); diff --git a/plugins/tech-radar/api-report-alpha.md b/plugins/tech-radar/api-report-alpha.md index bcc9142223..34b035296e 100644 --- a/plugins/tech-radar/api-report-alpha.md +++ b/plugins/tech-radar/api-report-alpha.md @@ -17,10 +17,10 @@ const _default: BackstagePlugin< export default _default; // @alpha (undocumented) -export const sampleTechRadarApi: ExtensionDefinition<{}>; +export const techRadarApi: ExtensionDefinition<{}>; // @alpha (undocumented) -export const TechRadarPage: ExtensionDefinition<{ +export const techRadarPage: ExtensionDefinition<{ height: number; width: number; title: string; diff --git a/plugins/tech-radar/src/alpha.test.tsx b/plugins/tech-radar/src/alpha.test.tsx index 37d39c412b..71e5ab8df5 100644 --- a/plugins/tech-radar/src/alpha.test.tsx +++ b/plugins/tech-radar/src/alpha.test.tsx @@ -16,7 +16,7 @@ import { createExtensionTester } from '@backstage/frontend-test-utils'; import { screen } from '@testing-library/react'; -import { TechRadarPage, sampleTechRadarApi } from './alpha'; +import { techRadarPage, techRadarApi } from './alpha'; describe('TechRadarPage', () => { beforeAll(() => { @@ -27,7 +27,7 @@ describe('TechRadarPage', () => { }); it('renders without exploding', async () => { - createExtensionTester(TechRadarPage).add(sampleTechRadarApi).render(); + createExtensionTester(techRadarPage).add(techRadarApi).render(); await expect(screen.findByText('Tech Radar')).resolves.toBeInTheDocument(); }); diff --git a/plugins/tech-radar/src/alpha.tsx b/plugins/tech-radar/src/alpha.tsx index dfed6d3af0..1fb5fa06f3 100644 --- a/plugins/tech-radar/src/alpha.tsx +++ b/plugins/tech-radar/src/alpha.tsx @@ -31,7 +31,7 @@ import { import { rootRouteRef } from './plugin'; /** @alpha */ -export const TechRadarPage = createPageExtension({ +export const techRadarPage = createPageExtension({ defaultPath: '/tech-radar', routeRef: convertLegacyRouteRef(rootRouteRef), configSchema: createSchemaFromZod(z => @@ -53,14 +53,14 @@ export const TechRadarPage = createPageExtension({ }); /** @alpha */ -export const sampleTechRadarApi = createApiExtension({ +export const techRadarApi = createApiExtension({ factory: createApiFactory(techRadarApiRef, new SampleTechRadarApi()), }); /** @alpha */ export default createPlugin({ id: 'tech-radar', - extensions: [TechRadarPage, sampleTechRadarApi], + extensions: [techRadarPage, techRadarApi], routes: { root: convertLegacyRouteRef(rootRouteRef), }, diff --git a/plugins/techdocs/api-report-alpha.md b/plugins/techdocs/api-report-alpha.md index afc3202a43..cf9f5fa9a3 100644 --- a/plugins/techdocs/api-report-alpha.md +++ b/plugins/techdocs/api-report-alpha.md @@ -23,7 +23,7 @@ const _default: BackstagePlugin< export default _default; // @alpha (undocumented) -export const TechDocsSearchResultListItemExtension: ExtensionDefinition<{ +export const techDocsSearchResultListItemExtension: ExtensionDefinition<{ lineClamp: number; noTrack: boolean; asListItem: boolean; diff --git a/plugins/techdocs/src/alpha.tsx b/plugins/techdocs/src/alpha.tsx index 26891b23f0..ef564d469a 100644 --- a/plugins/techdocs/src/alpha.tsx +++ b/plugins/techdocs/src/alpha.tsx @@ -48,7 +48,7 @@ import { import { createEntityContentExtension } from '@backstage/plugin-catalog-react/alpha'; /** @alpha */ -const techDocsStorage = createApiExtension({ +const techDocsStorageApi = createApiExtension({ factory: createApiFactory({ api: techdocsStorageApiRef, deps: { @@ -68,7 +68,7 @@ const techDocsStorage = createApiExtension({ }); /** @alpha */ -const techDocsClient = createApiExtension({ +const techDocsClientApi = createApiExtension({ factory: createApiFactory({ api: techdocsApiRef, deps: { @@ -86,7 +86,7 @@ const techDocsClient = createApiExtension({ }); /** @alpha */ -export const TechDocsSearchResultListItemExtension = +export const techDocsSearchResultListItemExtension = createSearchResultListItemExtension({ configSchema: createSchemaFromZod(z => z.object({ @@ -113,7 +113,7 @@ export const TechDocsSearchResultListItemExtension = * * @alpha */ -const TechDocsIndexPage = createPageExtension({ +const techDocsPage = createPageExtension({ defaultPath: '/docs', routeRef: convertLegacyRouteRef(rootRouteRef), loader: () => @@ -127,7 +127,7 @@ const TechDocsIndexPage = createPageExtension({ * * @alpha */ -const TechDocsReaderPage = createPageExtension({ +const techDocsReaderPage = createPageExtension({ name: 'reader', defaultPath: '/docs/:namespace/:kind/:name', routeRef: convertLegacyRouteRef(rootDocsRouteRef), @@ -142,7 +142,7 @@ const TechDocsReaderPage = createPageExtension({ * * @alpha */ -const TechDocsEntityContent = createEntityContentExtension({ +const techDocsEntityContent = createEntityContentExtension({ defaultPath: 'docs', defaultTitle: 'TechDocs', loader: () => @@ -150,7 +150,7 @@ const TechDocsEntityContent = createEntityContentExtension({ }); /** @alpha */ -const TechDocsNavItem = createNavItemExtension({ +const techDocsNavItem = createNavItemExtension({ icon: LibraryBooks, title: 'Docs', routeRef: convertLegacyRouteRef(rootRouteRef), @@ -160,13 +160,13 @@ const TechDocsNavItem = createNavItemExtension({ export default createPlugin({ id: 'techdocs', extensions: [ - techDocsClient, - techDocsStorage, - TechDocsNavItem, - TechDocsIndexPage, - TechDocsReaderPage, - TechDocsEntityContent, - TechDocsSearchResultListItemExtension, + techDocsClientApi, + techDocsStorageApi, + techDocsNavItem, + techDocsPage, + techDocsReaderPage, + techDocsEntityContent, + techDocsSearchResultListItemExtension, ], routes: { root: convertLegacyRouteRef(rootRouteRef), diff --git a/plugins/user-settings/src/alpha.tsx b/plugins/user-settings/src/alpha.tsx index 9ee2e4a7c5..06590d839a 100644 --- a/plugins/user-settings/src/alpha.tsx +++ b/plugins/user-settings/src/alpha.tsx @@ -29,7 +29,7 @@ import React from 'react'; export * from './translation'; -const UserSettingsPage = createPageExtension({ +const userSettingsPage = createPageExtension({ defaultPath: '/settings', routeRef: convertLegacyRouteRef(settingsRouteRef), inputs: { @@ -55,7 +55,7 @@ const UserSettingsPage = createPageExtension({ */ export default createPlugin({ id: 'user-settings', - extensions: [UserSettingsPage], + extensions: [userSettingsPage], routes: { root: convertLegacyRouteRef(settingsRouteRef), }, From 1ba820077de83376ee814030cc74792b17edbf29 Mon Sep 17 00:00:00 2001 From: Peter Macdonald Date: Wed, 13 Dec 2023 19:54:39 +0100 Subject: [PATCH 178/275] Adding DevQuotes Pluginto Marketplace Signed-off-by: Peter Macdonald --- microsite/data/plugins/dev-quotes.yaml | 10 ++++++++++ microsite/static/img/dqicon.png | Bin 0 -> 177132 bytes 2 files changed, 10 insertions(+) create mode 100644 microsite/data/plugins/dev-quotes.yaml create mode 100644 microsite/static/img/dqicon.png diff --git a/microsite/data/plugins/dev-quotes.yaml b/microsite/data/plugins/dev-quotes.yaml new file mode 100644 index 0000000000..df31bb80a6 --- /dev/null +++ b/microsite/data/plugins/dev-quotes.yaml @@ -0,0 +1,10 @@ +--- +title: Dev Quotes +author: Peter Macdonald +authorUrl: https://github.com/Parsifal-M +category: Humor +description: Displays a coding/progamming related quote designed as a footer for the Homepage, although to be honest it can be used anywhere you like! +documentation: https://github.com/Parsifal-M/backstage-dev-quotes?tab=readme-ov-file#dev-quotes-homepage +iconUrl: /img/dqicon.png +npmPackageName: '@parsifal-m/plugin-dev-quotes-homepage' +addedDate: '2023-12-13' \ No newline at end of file diff --git a/microsite/static/img/dqicon.png b/microsite/static/img/dqicon.png new file mode 100644 index 0000000000000000000000000000000000000000..3746841cd86110492e3f0c274461f65ca0f08b74 GIT binary patch literal 177132 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�&uz(ve=k^K-5L6OA)HgOFg|1lIAlJRnc&nkdg_ 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�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 literal 0 HcmV?d00001 From 51eea8ba85e538ed8cc36d9a350fe66f37c46912 Mon Sep 17 00:00:00 2001 From: Peter Macdonald Date: Wed, 13 Dec 2023 20:36:47 +0100 Subject: [PATCH 179/275] Adding missing newline? Signed-off-by: Peter Macdonald --- microsite/data/plugins/dev-quotes.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/microsite/data/plugins/dev-quotes.yaml b/microsite/data/plugins/dev-quotes.yaml index df31bb80a6..3569dd408b 100644 --- a/microsite/data/plugins/dev-quotes.yaml +++ b/microsite/data/plugins/dev-quotes.yaml @@ -7,4 +7,4 @@ description: Displays a coding/progamming related quote designed as a footer for documentation: https://github.com/Parsifal-M/backstage-dev-quotes?tab=readme-ov-file#dev-quotes-homepage iconUrl: /img/dqicon.png npmPackageName: '@parsifal-m/plugin-dev-quotes-homepage' -addedDate: '2023-12-13' \ No newline at end of file +addedDate: '2023-12-13' From 987d20e1046f6662fa4fe9d8f63d482c2189cecd Mon Sep 17 00:00:00 2001 From: Peter Macdonald Date: Wed, 13 Dec 2023 21:25:15 +0100 Subject: [PATCH 180/275] removed the offending whitespace Signed-off-by: Peter Macdonald --- microsite/data/plugins/dev-quotes.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/microsite/data/plugins/dev-quotes.yaml b/microsite/data/plugins/dev-quotes.yaml index 3569dd408b..ad2ac91e4c 100644 --- a/microsite/data/plugins/dev-quotes.yaml +++ b/microsite/data/plugins/dev-quotes.yaml @@ -2,7 +2,7 @@ title: Dev Quotes author: Peter Macdonald authorUrl: https://github.com/Parsifal-M -category: Humor +category: Humor description: Displays a coding/progamming related quote designed as a footer for the Homepage, although to be honest it can be used anywhere you like! documentation: https://github.com/Parsifal-M/backstage-dev-quotes?tab=readme-ov-file#dev-quotes-homepage iconUrl: /img/dqicon.png From 28949ea4aa6e2ac74cac0d66860406bad8be75fe Mon Sep 17 00:00:00 2001 From: Rutuja Marathe Date: Wed, 13 Dec 2023 16:05:41 -0500 Subject: [PATCH 181/275] feat: add github:autolinks:create action Signed-off-by: Rutuja Marathe --- .changeset/wild-crews-promise.md | 6 + .../api-report.md | 15 +++ .../actions/githubAutolinks.examples.test.ts | 90 +++++++++++++ .../src/actions/githubAutolinks.examples.ts | 38 ++++++ .../src/actions/githubAutolinks.test.ts | 125 ++++++++++++++++++ .../src/actions/githubAutolinks.ts | 118 +++++++++++++++++ .../src/actions/index.ts | 1 + .../actions/builtin/createBuiltinActions.ts | 5 + 8 files changed, 398 insertions(+) create mode 100644 .changeset/wild-crews-promise.md create mode 100644 plugins/scaffolder-backend-module-github/src/actions/githubAutolinks.examples.test.ts create mode 100644 plugins/scaffolder-backend-module-github/src/actions/githubAutolinks.examples.ts create mode 100644 plugins/scaffolder-backend-module-github/src/actions/githubAutolinks.test.ts create mode 100644 plugins/scaffolder-backend-module-github/src/actions/githubAutolinks.ts diff --git a/.changeset/wild-crews-promise.md b/.changeset/wild-crews-promise.md new file mode 100644 index 0000000000..e0095c3546 --- /dev/null +++ b/.changeset/wild-crews-promise.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-scaffolder-backend-module-github': patch +'@backstage/plugin-scaffolder-backend': patch +--- + +Add a new action for creating github-autolink references for a repository: `github:autolinks:create` diff --git a/plugins/scaffolder-backend-module-github/api-report.md b/plugins/scaffolder-backend-module-github/api-report.md index bb3ec4e7c4..920be79d12 100644 --- a/plugins/scaffolder-backend-module-github/api-report.md +++ b/plugins/scaffolder-backend-module-github/api-report.md @@ -31,6 +31,21 @@ export function createGithubActionsDispatchAction(options: { JsonObject >; +// @public +export function createGithubAutolinksAction(options: { + integrations: ScmIntegrations; + githubCredentialsProvider?: GithubCredentialsProvider; +}): TemplateAction< + { + repoUrl: string; + keyPrefix: string; + urlTemplate: string; + isAlphanumeric?: boolean | undefined; + token?: string | undefined; + }, + JsonObject +>; + // @public export function createGithubDeployKeyAction(options: { integrations: ScmIntegrationRegistry; diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubAutolinks.examples.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubAutolinks.examples.test.ts new file mode 100644 index 0000000000..612f68dea2 --- /dev/null +++ b/plugins/scaffolder-backend-module-github/src/actions/githubAutolinks.examples.test.ts @@ -0,0 +1,90 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { getVoidLogger } from '@backstage/backend-common'; +import { ConfigReader } from '@backstage/config'; +import { + DefaultGithubCredentialsProvider, + GithubCredentialsProvider, + ScmIntegrations, +} from '@backstage/integration'; +import { TemplateAction } from '@backstage/plugin-scaffolder-node'; +import { PassThrough } from 'stream'; +import { createGithubAutolinksAction } from './githubAutolinks'; +import { examples } from './githubAutolinks.examples'; +import yaml from 'yaml'; + +const mockOctokit = { + rest: { + repos: { + createAutolink: jest.fn(), + }, + }, +}; +jest.mock('octokit', () => ({ + Octokit: class { + constructor() { + return mockOctokit; + } + }, +})); + +describe('github:autolinks:create', () => { + const config = new ConfigReader({ + integrations: { + github: [ + { host: 'github.com', token: 'tokenlols' }, + { host: 'ghe.github.com' }, + ], + }, + }); + + const integrations = ScmIntegrations.fromConfig(config); + let githubCredentialsProvider: GithubCredentialsProvider; + let action: TemplateAction; + + it('should call the githubApis for creating autolink reference', async () => { + const input = yaml.parse(examples[0].example).steps[0].input; + githubCredentialsProvider = + DefaultGithubCredentialsProvider.fromIntegrations(integrations); + action = createGithubAutolinksAction({ + integrations, + githubCredentialsProvider, + }); + + mockOctokit.rest.repos.createAutolink.mockResolvedValue({ + data: { + id: '1', + }, + }); + await action.handler({ + input, + workspacePath: 'lol', + logger: getVoidLogger(), + logStream: new PassThrough(), + output: jest.fn(), + createTemporaryDirectory: jest.fn(), + }); + + expect(mockOctokit.rest.repos.createAutolink).toHaveBeenCalledWith({ + owner: 'owner', + repo: 'repo', + key_prefix: 'TICKET-', + url_template: 'https://example.com/TICKET?query=', + is_alphanumeric: false, + }); + }); +}); diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubAutolinks.examples.ts b/plugins/scaffolder-backend-module-github/src/actions/githubAutolinks.examples.ts new file mode 100644 index 0000000000..5acaeeb6e2 --- /dev/null +++ b/plugins/scaffolder-backend-module-github/src/actions/githubAutolinks.examples.ts @@ -0,0 +1,38 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { TemplateExample } from '@backstage/plugin-scaffolder-node'; +import yaml from 'yaml'; + +export const examples: TemplateExample[] = [ + { + description: 'GitHub alphanumric autolink reference', + example: yaml.stringify({ + steps: [ + { + action: 'github:autolinks:create', + name: 'Create an autolink reference', + input: { + repoUrl: 'github.com?repo=repo&owner=owner', + keyPrefix: 'TICKET-', + urlTemplate: 'https://example.com/TICKET?query=', + isAlphanumeric: false, + }, + }, + ], + }), + }, +]; diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubAutolinks.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubAutolinks.test.ts new file mode 100644 index 0000000000..95c0226104 --- /dev/null +++ b/plugins/scaffolder-backend-module-github/src/actions/githubAutolinks.test.ts @@ -0,0 +1,125 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { getVoidLogger } from '@backstage/backend-common'; +import { ConfigReader } from '@backstage/config'; +import { + DefaultGithubCredentialsProvider, + GithubCredentialsProvider, + ScmIntegrations, +} from '@backstage/integration'; +import { TemplateAction } from '@backstage/plugin-scaffolder-node'; +import { PassThrough } from 'stream'; +import { createGithubAutolinksAction } from './githubAutolinks'; + +const mockOctokit = { + rest: { + repos: { + createAutolink: jest.fn(), + }, + }, +}; +jest.mock('octokit', () => ({ + Octokit: class { + constructor() { + return mockOctokit; + } + }, +})); + +describe('github:autolinks:create', () => { + const config = new ConfigReader({ + integrations: { + github: [ + { host: 'github.com', token: 'tokenlols' }, + { host: 'ghe.github.com' }, + ], + }, + }); + + const integrations = ScmIntegrations.fromConfig(config); + let githubCredentialsProvider: GithubCredentialsProvider; + let action: TemplateAction; + const mockContext = { + workspacePath: 'lol', + logger: getVoidLogger(), + logStream: new PassThrough(), + output: jest.fn(), + createTemporaryDirectory: jest.fn(), + }; + + it('should call the githubApis for creating alphanumeric autolink reference', async () => { + githubCredentialsProvider = + DefaultGithubCredentialsProvider.fromIntegrations(integrations); + action = createGithubAutolinksAction({ + integrations, + githubCredentialsProvider, + }); + + mockOctokit.rest.repos.createAutolink.mockResolvedValue({ + data: { + id: '1', + }, + }); + await action.handler({ + input: { + repoUrl: 'github.com?repo=repo&owner=owner', + keyPrefix: 'TICKET-', + urlTemplate: 'https://example.com/TICKET?query=', + }, + ...mockContext, + }); + + expect(mockOctokit.rest.repos.createAutolink).toHaveBeenCalledWith({ + owner: 'owner', + repo: 'repo', + key_prefix: 'TICKET-', + url_template: 'https://example.com/TICKET?query=', + }); + }); + + it('should call the githubApis for creating numeric autolink reference', async () => { + githubCredentialsProvider = + DefaultGithubCredentialsProvider.fromIntegrations(integrations); + action = createGithubAutolinksAction({ + integrations, + githubCredentialsProvider, + }); + + mockOctokit.rest.repos.createAutolink.mockResolvedValue({ + data: { + id: '1', + }, + }); + await action.handler({ + input: { + repoUrl: 'github.com?repo=repo&owner=owner', + keyPrefix: 'TICKET-', + urlTemplate: 'https://example.com/TICKET?query=', + isAlphanumeric: false, + }, + ...mockContext, + }); + + expect(mockOctokit.rest.repos.createAutolink).toHaveBeenCalledWith({ + owner: 'owner', + repo: 'repo', + key_prefix: 'TICKET-', + url_template: 'https://example.com/TICKET?query=', + is_alphanumeric: false, + }); + }); +}); diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubAutolinks.ts b/plugins/scaffolder-backend-module-github/src/actions/githubAutolinks.ts new file mode 100644 index 0000000000..4b0d0e1e1f --- /dev/null +++ b/plugins/scaffolder-backend-module-github/src/actions/githubAutolinks.ts @@ -0,0 +1,118 @@ +/* + * 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 { + GithubCredentialsProvider, + ScmIntegrations, +} from '@backstage/integration'; +import { + createTemplateAction, + parseRepoUrl, +} from '@backstage/plugin-scaffolder-node'; +import { Octokit } from 'octokit'; +import { examples } from './githubAutolinks.examples'; +import { getOctokitOptions } from './helpers'; + +/** + * Create an autolink reference for a repository + * @public + */ +export function createGithubAutolinksAction(options: { + integrations: ScmIntegrations; + githubCredentialsProvider?: GithubCredentialsProvider; +}) { + const { integrations, githubCredentialsProvider } = options; + + return createTemplateAction<{ + repoUrl: string; + keyPrefix: string; + urlTemplate: string; + isAlphanumeric?: boolean; + token?: string; + }>({ + id: 'github:autolinks:create', + description: 'Create an autolink reference for a repository', + examples, + schema: { + input: { + type: 'object', + required: ['repoUrl', 'keyPrefix', 'urlTemplate'], + properties: { + repoUrl: { + title: 'Repository Location', + description: `Accepts the format 'github.com?repo=reponame&owner=owner' where 'reponame' is the new repository name and 'owner' is an organization or username`, + type: 'string', + }, + keyPrefix: { + title: 'Key Prefix', + description: + 'This prefix appended by certain characters will generate a link any time it is found in an issue, pull request, or commit.', + type: 'string', + }, + urlTemplate: { + title: 'URL Template', + description: + 'The URL must contain for the reference number. matches different characters depending on the value of isAlphanumeric.', + type: 'string', + }, + isAlphanumeric: { + title: 'Alphanumeric', + description: + 'Whether this autolink reference matches alphanumeric characters. If true, the parameter of the url_template matches alphanumeric characters A-Z (case insensitive), 0-9, and -. If false, this autolink reference only matches numeric characters. Default: true', + type: 'boolean', + }, + token: { + title: 'Authentication Token', + type: 'string', + description: 'The token to use for authorization to GitHub', + }, + }, + }, + }, + async handler(ctx) { + const { repoUrl, keyPrefix, urlTemplate, isAlphanumeric, token } = + ctx.input; + + ctx.logger.info(`Creating autolink reference for repo ${repoUrl}`); + + const { owner, repo } = parseRepoUrl(repoUrl, integrations); + + if (!owner) { + throw new InputError('Invalid repository owner provided in repoUrl'); + } + + const client = new Octokit( + await getOctokitOptions({ + integrations, + repoUrl, + credentialsProvider: githubCredentialsProvider, + token, + }), + ); + + await client.rest.repos.createAutolink({ + owner, + repo, + key_prefix: keyPrefix, + url_template: urlTemplate, + is_alphanumeric: isAlphanumeric, + }); + + ctx.logger.info(`Autolink reference created successfully`); + }, + }); +} diff --git a/plugins/scaffolder-backend-module-github/src/actions/index.ts b/plugins/scaffolder-backend-module-github/src/actions/index.ts index ebcda41d93..27eaca0e85 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/index.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/index.ts @@ -27,3 +27,4 @@ export { type CreateGithubPullRequestActionOptions, } from './githubPullRequest'; export { createPublishGithubAction } from './github'; +export { createGithubAutolinksAction } from './githubAutolinks'; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts index 6fc50c6453..dfef2d3c92 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts @@ -42,6 +42,7 @@ import { } from './filesystem'; import { createGithubActionsDispatchAction, + createGithubAutolinksAction, createGithubDeployKeyAction, createGithubEnvironmentAction, createGithubIssuesLabelAction, @@ -218,6 +219,10 @@ export const createBuiltinActions = ( createGithubDeployKeyAction({ integrations, }), + createGithubAutolinksAction({ + integrations, + githubCredentialsProvider, + }), ]; return actions as TemplateAction[]; From 67409cbfe5d03d5f845c8c2097a6947a766183db Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Wed, 13 Dec 2023 16:43:24 +0100 Subject: [PATCH 182/275] refactor(frontend-test-utils): simplying core nav and router for test apps Signed-off-by: Camila Belo --- .../src/wiring/createApp.test.tsx | 19 ++ packages/frontend-test-utils/package.json | 3 +- .../src/app/createExtensionTester.test.tsx | 6 +- .../src/app/createExtensionTester.ts | 136 -------- .../src/app/createExtensionTester.tsx | 301 ++++++++++++++++++ .../src/app/renderInTestApp.test.tsx | 4 +- yarn.lock | 1 + 7 files changed, 327 insertions(+), 143 deletions(-) delete mode 100644 packages/frontend-test-utils/src/app/createExtensionTester.ts create mode 100644 packages/frontend-test-utils/src/app/createExtensionTester.tsx diff --git a/packages/frontend-app-api/src/wiring/createApp.test.tsx b/packages/frontend-app-api/src/wiring/createApp.test.tsx index dafad5365c..338d293132 100644 --- a/packages/frontend-app-api/src/wiring/createApp.test.tsx +++ b/packages/frontend-app-api/src/wiring/createApp.test.tsx @@ -210,6 +210,25 @@ describe('createApp', () => { ] + apis [ + + + + + + + + + + + + + + + + + + ] " `); }); diff --git a/packages/frontend-test-utils/package.json b/packages/frontend-test-utils/package.json index 9ca546721f..33b1f41a8c 100644 --- a/packages/frontend-test-utils/package.json +++ b/packages/frontend-test-utils/package.json @@ -39,6 +39,7 @@ }, "peerDependencies": { "@testing-library/react": "^12.1.3 || ^13.0.0 || ^14.0.0", - "react": "^16.13.1 || ^17.0.0 || ^18.0.0" + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" } } diff --git a/packages/frontend-test-utils/src/app/createExtensionTester.test.tsx b/packages/frontend-test-utils/src/app/createExtensionTester.test.tsx index bdcefb7b8b..de52ca52de 100644 --- a/packages/frontend-test-utils/src/app/createExtensionTester.test.tsx +++ b/packages/frontend-test-utils/src/app/createExtensionTester.test.tsx @@ -103,7 +103,7 @@ describe('createExtensionTester', () => { ).resolves.toBeInTheDocument(); }); - it.skip('should accepts a custom config', async () => { + it('should accepts a custom config', async () => { const indexPageExtension = createExtension({ ...defaultDefinition, configSchema: createSchemaFromZod(z => @@ -175,7 +175,7 @@ describe('createExtensionTester', () => { ).resolves.toBeInTheDocument(); }); - it.skip('should capture click events in anylitics', async () => { + it('should capture click events in anylitics', async () => { // Mocking the analytics api implementation const analyticsApiMock = new MockAnalyticsApi(); @@ -219,7 +219,7 @@ describe('createExtensionTester', () => { fireEvent.click(await screen.findByRole('button', { name: 'See details' })); await waitFor(() => - expect(analyticsApiMock.getEvents()[1]).toMatchObject({ + expect(analyticsApiMock.getEvents()[0]).toMatchObject({ action: 'click', subject: 'See details', }), diff --git a/packages/frontend-test-utils/src/app/createExtensionTester.ts b/packages/frontend-test-utils/src/app/createExtensionTester.ts deleted file mode 100644 index 18c3c84ec9..0000000000 --- a/packages/frontend-test-utils/src/app/createExtensionTester.ts +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { createSpecializedApp } from '@backstage/frontend-app-api'; -import { - ExtensionDefinition, - coreExtensionData, - createExtension, - createExtensionOverrides, -} from '@backstage/frontend-plugin-api'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { resolveExtensionDefinition } from '../../../frontend-plugin-api/src/wiring/resolveExtensionDefinition'; -import { MockConfigApi } from '@backstage/test-utils'; -import { JsonArray, JsonObject, JsonValue } from '@backstage/types'; -import { RenderResult, render } from '@testing-library/react'; - -/** @public */ -export class ExtensionTester { - /** @internal */ - static forSubject( - subject: ExtensionDefinition, - options?: { config?: TConfig }, - ): ExtensionTester { - const tester = new ExtensionTester(); - const { output, factory, ...rest } = subject; - // attaching to core/routes to render as index route - const extension = createExtension({ - ...rest, - attachTo: { id: 'core/routes', input: 'routes' }, - output: { - ...output, - path: coreExtensionData.routePath, - }, - factory: params => ({ - ...factory(params), - path: '/', - }), - }); - tester.add(extension, options); - return tester; - } - - readonly #extensions = new Array<{ - id: string; - definition: ExtensionDefinition; - config?: JsonValue; - }>(); - - add( - extension: ExtensionDefinition, - options?: { config?: TConfig }, - ): ExtensionTester { - const { name, namespace } = extension; - - const definition = { - ...extension, - // setting name "test" as fallback - name: !namespace && !name ? 'test' : name, - }; - - const { id } = resolveExtensionDefinition(definition); - - this.#extensions.push({ - id, - definition, - config: options?.config as JsonValue, - }); - - return this; - } - - render(options?: { config?: JsonObject }): RenderResult { - const { config = {} } = options ?? {}; - - const [subject, ...rest] = this.#extensions; - if (!subject) { - throw new Error( - 'No subject found. At least one extension should be added to the tester.', - ); - } - - const extensionsConfig: JsonArray = [ - ...rest.map(extension => ({ - [extension.id]: { - config: extension.config, - }, - })), - { - [subject.id]: { - config: subject.config, - disabled: false, - }, - }, - ]; - - const finalConfig = { - ...config, - app: { - ...(typeof config.app === 'object' ? config.app : undefined), - extensions: extensionsConfig, - }, - }; - - const app = createSpecializedApp({ - features: [ - createExtensionOverrides({ - extensions: this.#extensions.map(extension => extension.definition), - }), - ], - config: new MockConfigApi(finalConfig), - }); - - return render(app.createRoot()); - } -} - -/** @public */ -export function createExtensionTester( - subject: ExtensionDefinition, - options?: { config?: TConfig }, -): ExtensionTester { - return ExtensionTester.forSubject(subject, options); -} diff --git a/packages/frontend-test-utils/src/app/createExtensionTester.tsx b/packages/frontend-test-utils/src/app/createExtensionTester.tsx new file mode 100644 index 0000000000..0404cf1ade --- /dev/null +++ b/packages/frontend-test-utils/src/app/createExtensionTester.tsx @@ -0,0 +1,301 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React, { ComponentType, ReactNode, useContext, useState } from 'react'; +import { MemoryRouter } from 'react-router-dom'; +import { Link } from '@backstage/core-components'; +import { RenderResult, render } from '@testing-library/react'; +import { createSpecializedApp } from '@backstage/frontend-app-api'; +import { + ExtensionDefinition, + IconComponent, + IdentityApi, + RouteRef, + configApiRef, + coreExtensionData, + createExtension, + createExtensionInput, + createExtensionOverrides, + createNavItemExtension, + useApi, + useRouteRef, +} from '@backstage/frontend-plugin-api'; +import { MockConfigApi } from '@backstage/test-utils'; +import { JsonArray, JsonObject, JsonValue } from '@backstage/types'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { resolveExtensionDefinition } from '../../../frontend-plugin-api/src/wiring/resolveExtensionDefinition'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { createSignInPageExtension } from '../../../frontend-plugin-api/src/extensions/createSignInPageExtension'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { InternalExtensionDefinition } from '../../../frontend-plugin-api/src/wiring/createExtension'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { InternalAppContext } from '../../../frontend-app-api/src/wiring/InternalAppContext'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { SignInPageProps } from '../../../core-plugin-api'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { getBasePath } from '../../../core-app-api/src/app/AppRouter'; + +const NavItem = (props: { + routeRef: RouteRef; + title: string; + icon: IconComponent; +}) => { + const { routeRef, title, icon: Icon } = props; + const to = useRouteRef(routeRef)(); + return ( +
  • + + {title} + +
  • + ); +}; + +const TestCoreNavExtension = createExtension({ + namespace: 'core', + name: 'nav', + attachTo: { id: 'core/layout', input: 'nav' }, + inputs: { + items: createExtensionInput({ + target: createNavItemExtension.targetDataRef, + }), + }, + output: { + element: coreExtensionData.reactElement, + }, + factory({ inputs }) { + return { + element: ( + + ), + }; + }, +}); + +const AuthenticationProvider = (props: { + signInPage?: ComponentType; + children: ReactNode; +}) => { + const { signInPage: SignInPage, children } = props; + const configApi = useApi(configApiRef); + const signOutTargetUrl = getBasePath(configApi) || '/'; + + const internalAppContext = useContext(InternalAppContext); + if (!internalAppContext) { + throw new Error('AppRouter must be rendered within the AppProvider'); + } + + const { appIdentityProxy } = internalAppContext; + const [identityApi, setIdentityApi] = useState(); + + if (!SignInPage) { + appIdentityProxy.setTarget( + { + getUserId: () => 'guest', + getIdToken: async () => undefined, + getProfile: () => ({ + email: 'guest@example.com', + displayName: 'Guest', + }), + getProfileInfo: async () => ({ + email: 'guest@example.com', + displayName: 'Guest', + }), + getBackstageIdentity: async () => ({ + type: 'user', + userEntityRef: 'user:default/guest', + ownershipEntityRefs: ['user:default/guest'], + }), + getCredentials: async () => ({}), + signOut: async () => {}, + }, + { signOutTargetUrl }, + ); + + return children; + } + + if (!identityApi) { + return ; + } + + appIdentityProxy.setTarget(identityApi, { + signOutTargetUrl, + }); + + return children; +}; + +const TestCoreRouterExtension = createExtension({ + namespace: 'core', + name: 'router', + attachTo: { id: 'core', input: 'root' }, + inputs: { + signInPage: createExtensionInput( + { + component: createSignInPageExtension.componentDataRef, + }, + { singleton: true, optional: true }, + ), + children: createExtensionInput( + { + element: coreExtensionData.reactElement, + }, + { singleton: true }, + ), + }, + output: { + element: coreExtensionData.reactElement, + }, + factory({ inputs }) { + const SignInPage = inputs.signInPage?.output.component; + const children = inputs.children.output.element; + + return { + element: ( + + + {children} + + + ), + }; + }, +}); + +/** @public */ +export class ExtensionTester { + /** @internal */ + static forSubject( + subject: ExtensionDefinition, + options?: { config?: TConfig }, + ): ExtensionTester { + const tester = new ExtensionTester(); + const { output, factory, ...rest } = + subject as InternalExtensionDefinition; + // attaching to core/routes to render as index route + const extension = createExtension({ + ...rest, + attachTo: { id: 'core/routes', input: 'routes' }, + output: { + ...output, + path: coreExtensionData.routePath, + }, + factory: params => ({ + ...factory(params), + path: '/', + }), + }); + tester.add(extension, options); + return tester; + } + + readonly #extensions = new Array<{ + id: string; + definition: ExtensionDefinition; + config?: JsonValue; + }>(); + + add( + extension: ExtensionDefinition, + options?: { config?: TConfig }, + ): ExtensionTester { + const { name, namespace } = extension; + + const definition = { + ...extension, + // setting name "test" as fallback + name: !namespace && !name ? 'test' : name, + }; + + const { id } = resolveExtensionDefinition(definition); + + this.#extensions.push({ + id, + definition, + config: options?.config as JsonValue, + }); + + return this; + } + + render(options?: { config?: JsonObject }): RenderResult { + const { config = {} } = options ?? {}; + + const [subject, ...rest] = this.#extensions; + if (!subject) { + throw new Error( + 'No subject found. At least one extension should be added to the tester.', + ); + } + + const extensionsConfig: JsonArray = [ + ...rest.map(extension => ({ + [extension.id]: { + config: extension.config, + }, + })), + { + [subject.id]: { + config: subject.config, + disabled: false, + }, + }, + ]; + + const finalConfig = { + ...config, + app: { + ...(typeof config.app === 'object' ? config.app : undefined), + extensions: extensionsConfig, + }, + }; + + const app = createSpecializedApp({ + features: [ + createExtensionOverrides({ + extensions: [ + ...this.#extensions.map(extension => extension.definition), + TestCoreNavExtension, + TestCoreRouterExtension, + ], + }), + ], + config: new MockConfigApi(finalConfig), + }); + + return render(app.createRoot()); + } +} + +/** @public */ +export function createExtensionTester( + subject: ExtensionDefinition, + options?: { config?: TConfig }, +): ExtensionTester { + return ExtensionTester.forSubject(subject, options); +} diff --git a/packages/frontend-test-utils/src/app/renderInTestApp.test.tsx b/packages/frontend-test-utils/src/app/renderInTestApp.test.tsx index d51f66010c..a6783d43a3 100644 --- a/packages/frontend-test-utils/src/app/renderInTestApp.test.tsx +++ b/packages/frontend-test-utils/src/app/renderInTestApp.test.tsx @@ -56,9 +56,7 @@ describe('renderInTestApp', () => { fireEvent.click(screen.getByRole('link', { name: 'See details' })); - const events = analyticsApiMock.getEvents(); - - expect(events[1]).toMatchObject({ + expect(analyticsApiMock.getEvents()[0]).toMatchObject({ action: 'click', subject: 'See details', }); diff --git a/yarn.lock b/yarn.lock index 8689a6ad0d..910432180d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4237,6 +4237,7 @@ __metadata: peerDependencies: "@testing-library/react": ^12.1.3 || ^13.0.0 || ^14.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 languageName: unknown linkType: soft From 44735df63341380ee27da62ccf154b7025254c75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Thu, 14 Dec 2023 10:33:44 +0100 Subject: [PATCH 183/275] no more featureLoader MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/fluffy-bikes-laugh.md | 5 +++ packages/frontend-app-api/api-report.md | 8 +++- packages/frontend-app-api/package.json | 1 + .../src/wiring/createApp.test.tsx | 27 +++++++++++++ .../frontend-app-api/src/wiring/createApp.tsx | 39 +++++++++++++++---- packages/frontend-app-api/src/wiring/index.ts | 1 + yarn.lock | 1 + 7 files changed, 72 insertions(+), 10 deletions(-) create mode 100644 .changeset/fluffy-bikes-laugh.md diff --git a/.changeset/fluffy-bikes-laugh.md b/.changeset/fluffy-bikes-laugh.md new file mode 100644 index 0000000000..40be65c126 --- /dev/null +++ b/.changeset/fluffy-bikes-laugh.md @@ -0,0 +1,5 @@ +--- +'@backstage/frontend-app-api': minor +--- + +Removed `featureLoader` from `createApp`, `features` instead accepts both `FrontendFeature` and `CreateAppFeatureLoader` diff --git a/packages/frontend-app-api/api-report.md b/packages/frontend-app-api/api-report.md index a4654e9f8d..08db759511 100644 --- a/packages/frontend-app-api/api-report.md +++ b/packages/frontend-app-api/api-report.md @@ -14,16 +14,20 @@ import { SubRouteRef } from '@backstage/frontend-plugin-api'; // @public (undocumented) export function createApp(options?: { - features?: FrontendFeature[]; + features?: (FrontendFeature | CreateAppFeatureLoader)[]; configLoader?: () => Promise<{ config: ConfigApi; }>; bindRoutes?(context: { bind: CreateAppRouteBinder }): void; - featureLoader?: (ctx: { config: ConfigApi }) => Promise; }): { createRoot(): JSX_2.Element; }; +// @public +export type CreateAppFeatureLoader = (options: { + config: ConfigApi; +}) => Promise; + // @public export type CreateAppRouteBinder = < TExternalRoutes extends { diff --git a/packages/frontend-app-api/package.json b/packages/frontend-app-api/package.json index 11f7260a20..db4dc931f2 100644 --- a/packages/frontend-app-api/package.json +++ b/packages/frontend-app-api/package.json @@ -38,6 +38,7 @@ "@backstage/core-app-api": "workspace:^", "@backstage/core-components": "workspace:^", "@backstage/core-plugin-api": "workspace:^", + "@backstage/errors": "workspace:^", "@backstage/frontend-plugin-api": "workspace:^", "@backstage/theme": "workspace:^", "@backstage/types": "workspace:^", diff --git a/packages/frontend-app-api/src/wiring/createApp.test.tsx b/packages/frontend-app-api/src/wiring/createApp.test.tsx index dafad5365c..a7956137c4 100644 --- a/packages/frontend-app-api/src/wiring/createApp.test.tsx +++ b/packages/frontend-app-api/src/wiring/createApp.test.tsx @@ -99,6 +99,33 @@ describe('createApp', () => { ); }); + it('should support feature loaders', async () => { + const app = createApp({ + configLoader: async () => ({ + config: new MockConfigApi({ key: 'config-value' }), + }), + features: [ + async ({ config }) => [ + createPlugin({ + id: 'test', + extensions: [ + createPageExtension({ + defaultPath: '/', + loader: async () =>
    {config.getString('key')}
    , + }), + ], + }), + ], + ], + }); + + await renderWithEffects(app.createRoot()); + + await expect( + screen.findByText('config-value'), + ).resolves.toBeInTheDocument(); + }); + it('should register feature flags', async () => { const app = createApp({ configLoader: async () => ({ config: new MockConfigApi({}) }), diff --git a/packages/frontend-app-api/src/wiring/createApp.tsx b/packages/frontend-app-api/src/wiring/createApp.tsx index 0f8e3de953..f3b32db399 100644 --- a/packages/frontend-app-api/src/wiring/createApp.tsx +++ b/packages/frontend-app-api/src/wiring/createApp.tsx @@ -101,6 +101,7 @@ import { toInternalBackstagePlugin } from '../../../frontend-plugin-api/src/wiri // eslint-disable-next-line @backstage/no-relative-monorepo-imports import { toInternalExtensionOverrides } from '../../../frontend-plugin-api/src/wiring/createExtensionOverrides'; import { DefaultComponentsApi } from '../apis/implementations/ComponentsApi'; +import { stringifyError } from '@backstage/errors'; export const builtinExtensions = [ Core, @@ -238,12 +239,20 @@ function deduplicateFeatures( .reverse(); } +/** + * A source of dynamically loaded frontend features. + * + * @public + */ +export type CreateAppFeatureLoader = (options: { + config: ConfigApi; +}) => Promise; + /** @public */ export function createApp(options?: { - features?: FrontendFeature[]; + features?: (FrontendFeature | CreateAppFeatureLoader)[]; configLoader?: () => Promise<{ config: ConfigApi }>; bindRoutes?(context: { bind: CreateAppRouteBinder }): void; - featureLoader?: (ctx: { config: ConfigApi }) => Promise; }): { createRoot(): JSX.Element; } { @@ -255,15 +264,28 @@ export function createApp(options?: { ); const discoveredFeatures = getAvailableFeatures(config); - const loadedFeatures = (await options?.featureLoader?.({ config })) ?? []; + + const providedFeatures: FrontendFeature[] = []; + for (const feature of options?.features ?? []) { + if (typeof feature === 'function') { + try { + const loadedFeatures = await feature({ config }); + providedFeatures.push(...loadedFeatures); + } catch (e) { + throw new Error( + `Failed to read frontend features from loader, ${stringifyError( + e, + )}`, + ); + } + } else { + providedFeatures.push(feature); + } + } const app = createSpecializedApp({ config, - features: [ - ...discoveredFeatures, - ...loadedFeatures, - ...(options?.features ?? []), - ], + features: [...discoveredFeatures, ...providedFeatures], bindRoutes: options?.bindRoutes, }).createRoot(); @@ -285,6 +307,7 @@ export function createApp(options?: { /** * Synchronous version of {@link createApp}, expecting all features and * config to have been loaded already. + * * @public */ export function createSpecializedApp(options?: { diff --git a/packages/frontend-app-api/src/wiring/index.ts b/packages/frontend-app-api/src/wiring/index.ts index 412e643523..00c6458bd5 100644 --- a/packages/frontend-app-api/src/wiring/index.ts +++ b/packages/frontend-app-api/src/wiring/index.ts @@ -18,6 +18,7 @@ export { createApp, createSpecializedApp, createExtensionTree, + type CreateAppFeatureLoader, type ExtensionTreeNode, type ExtensionTree, } from './createApp'; diff --git a/yarn.lock b/yarn.lock index 8a7e8a1dac..22ca9ef371 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4158,6 +4158,7 @@ __metadata: "@backstage/core-app-api": "workspace:^" "@backstage/core-components": "workspace:^" "@backstage/core-plugin-api": "workspace:^" + "@backstage/errors": "workspace:^" "@backstage/frontend-plugin-api": "workspace:^" "@backstage/test-utils": "workspace:^" "@backstage/theme": "workspace:^" From 8f5b7a0a6232923d17d65efcef8e4bd5251f4ffd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Thu, 14 Dec 2023 10:44:43 +0100 Subject: [PATCH 184/275] one more test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .../src/wiring/createApp.test.tsx | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/packages/frontend-app-api/src/wiring/createApp.test.tsx b/packages/frontend-app-api/src/wiring/createApp.test.tsx index a7956137c4..244ce625fb 100644 --- a/packages/frontend-app-api/src/wiring/createApp.test.tsx +++ b/packages/frontend-app-api/src/wiring/createApp.test.tsx @@ -126,6 +126,25 @@ describe('createApp', () => { ).resolves.toBeInTheDocument(); }); + it('should propagate errors thrown by feature loaders', async () => { + const app = createApp({ + configLoader: async () => ({ + config: new MockConfigApi({}), + }), + features: [ + async () => { + throw new TypeError('boom'); + }, + ], + }); + + await expect( + renderWithEffects(app.createRoot()), + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"Failed to read frontend features from loader, TypeError: boom"`, + ); + }); + it('should register feature flags', async () => { const app = createApp({ configLoader: async () => ({ config: new MockConfigApi({}) }), From df88d094c627de78296cf13da3cd66daf106bcf0 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Thu, 14 Dec 2023 12:10:18 +0100 Subject: [PATCH 185/275] Created a changeSet documenting the new gitea repo picker url Signed-off-by: cmoulliard --- .changeset/giant-pets-cover.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/giant-pets-cover.md diff --git a/.changeset/giant-pets-cover.md b/.changeset/giant-pets-cover.md new file mode 100644 index 0000000000..e26407e432 --- /dev/null +++ b/.changeset/giant-pets-cover.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': major +--- + +Add a new git repository url picker for `gitea`. This `GiteaRepoPicker` can be used in a template to scaffold a project to be cloned using gitea. From bae1e40f683e0b8d42562c1db0ef5904622e1619 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Thu, 14 Dec 2023 12:16:03 +0100 Subject: [PATCH 186/275] Revert the change from major to minor as code will not break current release Signed-off-by: cmoulliard --- .changeset/giant-pets-cover.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/giant-pets-cover.md b/.changeset/giant-pets-cover.md index e26407e432..604f39cf8d 100644 --- a/.changeset/giant-pets-cover.md +++ b/.changeset/giant-pets-cover.md @@ -1,5 +1,5 @@ --- -'@backstage/plugin-scaffolder': major +'@backstage/plugin-scaffolder': minor --- Add a new git repository url picker for `gitea`. This `GiteaRepoPicker` can be used in a template to scaffold a project to be cloned using gitea. From 5da4599d018b77c498f56f260bb6a19dfb8a7ff5 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Thu, 14 Dec 2023 13:33:06 +0100 Subject: [PATCH 187/275] Updating the api report for new gitea parameters Signed-off-by: cmoulliard --- plugins/scaffolder/api-report.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/scaffolder/api-report.md b/plugins/scaffolder/api-report.md index 6f8479990b..4df1eff430 100644 --- a/plugins/scaffolder/api-report.md +++ b/plugins/scaffolder/api-report.md @@ -379,6 +379,7 @@ export const RepoUrlPickerFieldExtension: FieldExtensionComponent_2< secretsKey: string; additionalScopes?: | { + gitea?: string[] | undefined; gerrit?: string[] | undefined; github?: string[] | undefined; gitlab?: string[] | undefined; @@ -405,6 +406,7 @@ export const RepoUrlPickerFieldSchema: FieldSchema< secretsKey: string; additionalScopes?: | { + gitea?: string[] | undefined; gerrit?: string[] | undefined; github?: string[] | undefined; gitlab?: string[] | undefined; From 35df801e094064a153b746662335f3ed00fe86b8 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 28 Oct 2023 14:10:26 +0200 Subject: [PATCH 188/275] app-next: initial app visualizer plugin Signed-off-by: Patrik Oldsberg --- packages/app-next/src/App.tsx | 2 ++ .../components/AppVisualizerPage.tsx | 21 ++++++++++++ .../src/plugins/app-visualizer/index.ts | 17 ++++++++++ .../src/plugins/app-visualizer/plugin.tsx | 33 +++++++++++++++++++ packages/app-next/src/plugins/index.ts | 19 +++++++++++ 5 files changed, 92 insertions(+) create mode 100644 packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage.tsx create mode 100644 packages/app-next/src/plugins/app-visualizer/index.ts create mode 100644 packages/app-next/src/plugins/app-visualizer/plugin.tsx create mode 100644 packages/app-next/src/plugins/index.ts diff --git a/packages/app-next/src/App.tsx b/packages/app-next/src/App.tsx index 0eca65fdda..09f454f302 100644 --- a/packages/app-next/src/App.tsx +++ b/packages/app-next/src/App.tsx @@ -32,6 +32,7 @@ import { createExtensionOverrides, } from '@backstage/frontend-plugin-api'; import techdocsPlugin from '@backstage/plugin-techdocs/alpha'; +import { plugins } from './plugins'; import { homePage } from './HomePage'; import { convertLegacyApp } from '@backstage/core-compat-api'; import { FlatRoutes } from '@backstage/core-app-api'; @@ -123,6 +124,7 @@ const app = createApp({ techdocsPlugin, userSettingsPlugin, homePlugin, + ...plugins, ...collectedLegacyPlugins, createExtensionOverrides({ extensions: [ diff --git a/packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage.tsx b/packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage.tsx new file mode 100644 index 0000000000..759b3870b9 --- /dev/null +++ b/packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage.tsx @@ -0,0 +1,21 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; + +export function AppVisualizerPage() { + return

    Hello world

    ; +} diff --git a/packages/app-next/src/plugins/app-visualizer/index.ts b/packages/app-next/src/plugins/app-visualizer/index.ts new file mode 100644 index 0000000000..63fd16c520 --- /dev/null +++ b/packages/app-next/src/plugins/app-visualizer/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { appVisualizerPlugin } from './plugin'; diff --git a/packages/app-next/src/plugins/app-visualizer/plugin.tsx b/packages/app-next/src/plugins/app-visualizer/plugin.tsx new file mode 100644 index 0000000000..c39cb9a6c3 --- /dev/null +++ b/packages/app-next/src/plugins/app-visualizer/plugin.tsx @@ -0,0 +1,33 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + createPageExtension, + createPlugin, +} from '@backstage/frontend-plugin-api'; +import React from 'react'; + +const appVisualizerPage = createPageExtension({ + id: 'plugin.app-visualizer.page', + defaultPath: '/visualizer', + loader: () => + import('./components/AppVisualizerPage').then(m => ), +}); + +export const appVisualizerPlugin = createPlugin({ + id: 'app-visualizer', + extensions: [appVisualizerPage], +}); diff --git a/packages/app-next/src/plugins/index.ts b/packages/app-next/src/plugins/index.ts new file mode 100644 index 0000000000..baafcde889 --- /dev/null +++ b/packages/app-next/src/plugins/index.ts @@ -0,0 +1,19 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { appVisualizerPlugin } from './app-visualizer'; + +export const plugins = [appVisualizerPlugin]; From d03fc971d65359b58b481f3ea42ee00b639bd1cf Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 28 Oct 2023 14:32:21 +0200 Subject: [PATCH 189/275] app-next: text tab for visualizer Signed-off-by: Patrik Oldsberg --- .../components/AppVisualizerPage.tsx | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage.tsx b/packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage.tsx index 759b3870b9..08e95305a2 100644 --- a/packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage.tsx +++ b/packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage.tsx @@ -14,8 +14,32 @@ * limitations under the License. */ +import { + Header, + Page, + TabbedLayout, + CodeSnippet, +} from '@backstage/core-components'; +import { useApi } from '@backstage/core-plugin-api'; +import { appTreeApiRef } from '@backstage/frontend-plugin-api'; import React from 'react'; export function AppVisualizerPage() { - return

    Hello world

    ; + const appTreeApi = useApi(appTreeApiRef); + const { tree } = appTreeApi.getTree(); + + return ( + +
    + + + + + + + ); } From 42ac760b44374cc0207b363c5d2b99a7af9bdaa6 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 30 Oct 2023 11:18:39 +0100 Subject: [PATCH 190/275] app-next: add graph visualizer Signed-off-by: Patrik Oldsberg --- .../AppVisualizerPage.tsx | 33 +-- .../AppVisualizerPage/GraphVisualizer.tsx | 266 ++++++++++++++++++ .../AppVisualizerPage/TextVisualizer.tsx | 116 ++++++++ .../components/AppVisualizerPage/index.ts | 17 ++ 4 files changed, 416 insertions(+), 16 deletions(-) rename packages/app-next/src/plugins/app-visualizer/components/{ => AppVisualizerPage}/AppVisualizerPage.tsx (56%) create mode 100644 packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage/GraphVisualizer.tsx create mode 100644 packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage/TextVisualizer.tsx create mode 100644 packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage/index.ts diff --git a/packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage.tsx b/packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage/AppVisualizerPage.tsx similarity index 56% rename from packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage.tsx rename to packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage/AppVisualizerPage.tsx index 08e95305a2..ec6145a1af 100644 --- a/packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage.tsx +++ b/packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage/AppVisualizerPage.tsx @@ -14,32 +14,33 @@ * limitations under the License. */ -import { - Header, - Page, - TabbedLayout, - CodeSnippet, -} from '@backstage/core-components'; +import { Content, Header, HeaderTabs, Page } from '@backstage/core-components'; import { useApi } from '@backstage/core-plugin-api'; import { appTreeApiRef } from '@backstage/frontend-plugin-api'; -import React from 'react'; +import Box from '@material-ui/core/Box'; +import React, { useState } from 'react'; +import { GraphVisualizer } from './GraphVisualizer'; +import { TextVisualizer } from './TextVisualizer'; export function AppVisualizerPage() { const appTreeApi = useApi(appTreeApiRef); const { tree } = appTreeApi.getTree(); + const [tab, setTab] = useState(0); + + const tabs = [ + { id: 'graph', label: 'Graph', element: }, + { id: 'text', label: 'Text', element: }, + ]; return (
    - - - - - + + + + {tabs[tab].element} + + ); } diff --git a/packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage/GraphVisualizer.tsx b/packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage/GraphVisualizer.tsx new file mode 100644 index 0000000000..cd41c45875 --- /dev/null +++ b/packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage/GraphVisualizer.tsx @@ -0,0 +1,266 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { AppNode, AppTree } from '@backstage/frontend-plugin-api'; +import Box from '@material-ui/core/Box'; +import Tooltip from '@material-ui/core/Tooltip'; +import * as colors from '@material-ui/core/colors'; +import { Theme, makeStyles } from '@material-ui/core/styles'; +import InputIcon from '@material-ui/icons/InputSharp'; +import React from 'react'; + +function createOutputColorGenerator(availableColors: string[]) { + const map = new Map(); + let i = 0; + + return function getOutputColor(id: string) { + let color = map.get(id); + if (color) { + return color; + } + color = availableColors[i]; + i += 1; + if (i >= availableColors.length) { + i = 0; + } + map.set(id, color); + return color; + }; +} + +const getOutputColor = createOutputColorGenerator([ + colors.green[500], + colors.blue[500], + colors.yellow[500], + colors.purple[500], + colors.orange[500], + colors.red[500], + colors.lime[500], + colors.green[200], + colors.blue[200], + colors.yellow[200], + colors.purple[200], + colors.orange[200], + colors.red[200], + colors.lime[200], +]); + +interface StyleProps { + enabled: boolean; +} + +function mainColor(theme: Theme) { + return ({ enabled }: StyleProps) => + enabled ? theme.palette.primary.main : colors.grey[600]; +} + +function hoverColor(theme: Theme) { + return ({ enabled }: StyleProps) => + enabled ? theme.palette.primary.dark : colors.grey[500]; +} + +const useStyles = makeStyles(theme => ({ + extension: { + borderLeftWidth: theme.spacing(1), + borderLeftStyle: 'solid', + borderLeftColor: mainColor(theme), + marginBottom: theme.spacing(0.5), + cursor: 'pointer', + fontSize: theme.typography.h6.fontSize, + + '&:hover': { + borderLeftColor: hoverColor(theme), + }, + '&:hover $extensionHeader': { + background: hoverColor(theme), + }, + }, + extensionHeader: { + display: 'flex', + flexFlow: 'row nowrap', + alignItems: 'center', + width: 'fit-content', + padding: theme.spacing(0.5, 1), + background: mainColor(theme), + }, + extensionHeaderId: { + flex: '0 0 auto', + color: theme.palette.primary.contrastText, + }, + extensionHeaderOutputs: { + margin: theme.spacing(0, 0.5), + marginTop: 1, + display: 'flex', + flexFlow: 'row nowrap', + alignItems: 'center', + }, + extensionTooltip: { + fontSize: theme.typography.h6.fontSize, + maxWidth: 'unset', + }, + output: { + marginLeft: theme.spacing(1), + width: theme.spacing(2.3), + height: theme.spacing(2.3), + borderRadius: '50%', + }, + outputId: { + maxWidth: 'unset', + padding: theme.spacing(1), + fontSize: theme.typography.h6.fontSize, + }, + extensionDisabledIcon: { + marginLeft: theme.spacing(1), + }, + attachments: {}, + attachmentsInput: () => ({ + marginBottom: theme.spacing(1), + + '&:not(:first-child) $attachmentsInputTitle': { + borderTopWidth: theme.spacing(1), + borderTopStyle: 'solid', + borderTopColor: mainColor(theme), + }, + '&:not(:first-child):hover $attachmentsInputTitle': { + borderTopColor: hoverColor(theme), + }, + }), + attachmentsInputTitle: () => ({ + display: 'flex', + flexFlow: 'row nowrap', + alignItems: 'center', + width: 'fit-content', + padding: theme.spacing(1, 2), + }), + attachmentsInputIcon: {}, + attachmentsInputName: { + marginLeft: theme.spacing(1), + color: theme.palette.text.primary, + }, + attachmentsInputChildren: { + marginLeft: theme.spacing(1), + }, +})); + +function Output(props: { id: string; enabled: boolean }) { + const { id, enabled } = props; + const classes = useStyles({ enabled }); + + return ( + +
    + + ); +} + +function Attachments(props: { + attachments: ReadonlyMap; + enabled: boolean; +}) { + const { attachments, enabled } = props; + + const classes = useStyles({ enabled }); + + if (attachments.size === 0) { + return null; + } + + return ( +
    + {[...attachments.entries()] + .sort(([a], [b]) => a.localeCompare(b)) + .map(([key, v]) => { + const children = v.sort((a, b) => a.spec.id.localeCompare(b.spec.id)); + + return ( +
    +
    + +
    {key}
    +
    +
    + {children.map(node => ( + + ))} +
    +
    + ); + })} +
    + ); +} + +function ExtensionTooltip(props: { node: AppNode }) { + const parts = []; + let node = props.node; + parts.push(node.spec.id); + while (node.edges.attachedTo) { + const input = node.edges.attachedTo.input; + node = node.edges.attachedTo.node; + parts.push(`${node.spec.id} [${input}]`); + } + parts.reverse(); + + return ( + <> + {parts.map(part => ( +
    {part}
    + ))} + + ); +} + +function Extension(props: { node: AppNode }) { + const { node } = props; + + const enabled = Boolean(node.instance); + const classes = useStyles({ enabled }); + + const dataRefIds = + node.instance && [...node.instance.getDataRefs()].map(r => r.id); + + return ( +
    +
    + } + classes={{ tooltip: classes.extensionTooltip }} + > +
    {node.spec.id}
    +
    +
    + {dataRefIds && + dataRefIds.length > 0 && + [...dataRefIds] + .sort() + .map(id => )} +
    +
    + +
    + ); +} + +export function GraphVisualizer({ tree }: { tree: AppTree }) { + return ( + + + + ); +} diff --git a/packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage/TextVisualizer.tsx b/packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage/TextVisualizer.tsx new file mode 100644 index 0000000000..50b1f61484 --- /dev/null +++ b/packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage/TextVisualizer.tsx @@ -0,0 +1,116 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { AppNode, AppTree } from '@backstage/frontend-plugin-api'; +import Box from '@material-ui/core/Box'; +import Checkbox from '@material-ui/core/Checkbox'; +import FormControlLabel from '@material-ui/core/FormControlLabel'; +import Paper from '@material-ui/core/Paper'; +import React, { ReactNode, useState } from 'react'; + +function mkDiv( + children: ReactNode, + options?: { indent?: boolean; key?: string | number; color?: string }, +) { + return ( +
    + {children} +
    + ); +} + +function nodeToText( + node: AppNode, + options?: { showOutputs?: boolean; showDisabled?: boolean }, +): ReactNode { + const dataRefIds = + node.instance && [...node.instance.getDataRefs()].map(r => r.id); + const out = + options?.showOutputs && dataRefIds && dataRefIds.length > 0 + ? ` out="${[...dataRefIds].sort().join(', ')}"` + : ''; + const color = node.instance ? undefined : 'gray'; + + if (node.edges.attachments.size === 0) { + return mkDiv(`<${node.spec.id}${out}/>`, { color }); + } + + return mkDiv([ + mkDiv(`<${node.spec.id}${out}>`, { key: 'start', color }), + ...[...node.edges.attachments.entries()] + .sort(([a], [b]) => a.localeCompare(b)) + .map(([key, v]) => { + const children = v + .filter(e => options?.showDisabled || e.instance) + .sort((a, b) => a.spec.id.localeCompare(b.spec.id)); + if (children.length === 0) { + return mkDiv(`${key} []`, { indent: true }); + } + return mkDiv( + [ + mkDiv(`${key} [`), + ...children.map(e => + mkDiv(nodeToText(e, options), { indent: true }), + ), + mkDiv(']'), + ], + { key, indent: true }, + ); + }), + mkDiv(``, { key: 'end', color }), + ]); +} + +export function TextVisualizer({ tree }: { tree: AppTree }) { + const [showOutputs, setShowOutputs] = useState(false); + const [showDisabled, setShowDisabled] = useState(false); + + return ( + <> + +
    + {nodeToText(tree.root, { showOutputs, showDisabled })} +
    +
    + + setShowOutputs(value)} + /> + } + label="Show Outputs" + /> + setShowDisabled(value)} + /> + } + label="Show Disabled" + /> + + + ); +} diff --git a/packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage/index.ts b/packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage/index.ts new file mode 100644 index 0000000000..971bc6ccb2 --- /dev/null +++ b/packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { AppVisualizerPage } from './AppVisualizerPage'; From 59d60e853b52a40be3755aa07361f7da760906ca Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 30 Oct 2023 12:12:28 +0100 Subject: [PATCH 191/275] app-next: app graph visualizer cleanup Signed-off-by: Patrik Oldsberg --- .../AppVisualizerPage/GraphVisualizer.tsx | 152 ++++++++---------- 1 file changed, 66 insertions(+), 86 deletions(-) diff --git a/packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage/GraphVisualizer.tsx b/packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage/GraphVisualizer.tsx index cd41c45875..f8b9ae2d72 100644 --- a/packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage/GraphVisualizer.tsx +++ b/packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage/GraphVisualizer.tsx @@ -17,9 +17,11 @@ import { AppNode, AppTree } from '@backstage/frontend-plugin-api'; import Box from '@material-ui/core/Box'; import Tooltip from '@material-ui/core/Tooltip'; +import Typography from '@material-ui/core/Typography'; import * as colors from '@material-ui/core/colors'; import { Theme, makeStyles } from '@material-ui/core/styles'; import InputIcon from '@material-ui/icons/InputSharp'; +import DisabledIcon from '@material-ui/icons/NotInterestedSharp'; import React from 'react'; function createOutputColorGenerator(availableColors: string[]) { @@ -62,30 +64,25 @@ interface StyleProps { enabled: boolean; } -function mainColor(theme: Theme) { +function borderColor(theme: Theme) { return ({ enabled }: StyleProps) => - enabled ? theme.palette.primary.main : colors.grey[600]; + enabled ? theme.palette.primary.main : theme.palette.divider; } -function hoverColor(theme: Theme) { - return ({ enabled }: StyleProps) => - enabled ? theme.palette.primary.dark : colors.grey[500]; -} +const config = { + borderWidth: 0.75, +}; const useStyles = makeStyles(theme => ({ extension: { - borderLeftWidth: theme.spacing(1), + borderLeftWidth: theme.spacing(config.borderWidth), borderLeftStyle: 'solid', - borderLeftColor: mainColor(theme), - marginBottom: theme.spacing(0.5), + borderLeftColor: borderColor(theme), cursor: 'pointer', - fontSize: theme.typography.h6.fontSize, - '&:hover': { - borderLeftColor: hoverColor(theme), - }, '&:hover $extensionHeader': { - background: hoverColor(theme), + color: ({ enabled }: StyleProps) => + enabled ? theme.palette.primary.main : theme.palette.text.secondary, }, }, extensionHeader: { @@ -93,77 +90,62 @@ const useStyles = makeStyles(theme => ({ flexFlow: 'row nowrap', alignItems: 'center', width: 'fit-content', + padding: theme.spacing(0.5, 1), - background: mainColor(theme), - }, - extensionHeaderId: { - flex: '0 0 auto', - color: theme.palette.primary.contrastText, + color: ({ enabled }: StyleProps) => + enabled ? theme.palette.text.primary : theme.palette.text.disabled, + background: theme.palette.background.paper, + + borderTopRightRadius: theme.shape.borderRadius, + borderBottomRightRadius: theme.shape.borderRadius, }, extensionHeaderOutputs: { - margin: theme.spacing(0, 0.5), - marginTop: 1, display: 'flex', flexFlow: 'row nowrap', alignItems: 'center', - }, - extensionTooltip: { - fontSize: theme.typography.h6.fontSize, - maxWidth: 'unset', - }, - output: { - marginLeft: theme.spacing(1), - width: theme.spacing(2.3), - height: theme.spacing(2.3), - borderRadius: '50%', - }, - outputId: { - maxWidth: 'unset', - padding: theme.spacing(1), - fontSize: theme.typography.h6.fontSize, - }, - extensionDisabledIcon: { marginLeft: theme.spacing(1), + gap: theme.spacing(1), }, attachments: {}, - attachmentsInput: () => ({ - marginBottom: theme.spacing(1), - - '&:not(:first-child) $attachmentsInputTitle': { - borderTopWidth: theme.spacing(1), - borderTopStyle: 'solid', - borderTopColor: mainColor(theme), + attachmentsInput: { + '&:first-child $attachmentsInputTitle': { + borderTop: 0, }, - '&:not(:first-child):hover $attachmentsInputTitle': { - borderTopColor: hoverColor(theme), - }, - }), - attachmentsInputTitle: () => ({ + }, + attachmentsInputTitle: { display: 'flex', flexFlow: 'row nowrap', alignItems: 'center', width: 'fit-content', - padding: theme.spacing(1, 2), - }), - attachmentsInputIcon: {}, + padding: theme.spacing(1), + + borderTopWidth: theme.spacing(config.borderWidth), + borderTopStyle: 'solid', + borderTopColor: borderColor(theme), + }, attachmentsInputName: { marginLeft: theme.spacing(1), - color: theme.palette.text.primary, }, attachmentsInputChildren: { + display: 'flex', + flexFlow: 'column nowrap', + alignItems: 'flex-start', + gap: theme.spacing(0.5), marginLeft: theme.spacing(1), + marginBottom: theme.spacing(1), }, })); -function Output(props: { id: string; enabled: boolean }) { - const { id, enabled } = props; - const classes = useStyles({ enabled }); +function Output(props: { id: string }) { + const { id } = props; return ( - -
    {id}}> + ); @@ -182,27 +164,29 @@ function Attachments(props: { } return ( -
    + {[...attachments.entries()] .sort(([a], [b]) => a.localeCompare(b)) .map(([key, v]) => { const children = v.sort((a, b) => a.spec.id.localeCompare(b.spec.id)); return ( -
    -
    - -
    {key}
    -
    -
    + + + + + {key} + + + {children.map(node => ( ))} -
    -
    +
    + ); })} -
    +
    ); } @@ -220,7 +204,7 @@ function ExtensionTooltip(props: { node: AppNode }) { return ( <> {parts.map(part => ( -
    {part}
    + {part} ))} ); @@ -236,24 +220,20 @@ function Extension(props: { node: AppNode }) { node.instance && [...node.instance.getDataRefs()].map(r => r.id); return ( -
    -
    - } - classes={{ tooltip: classes.extensionTooltip }} - > -
    {node.spec.id}
    + + + }> + {node.spec.id} -
    + {dataRefIds && dataRefIds.length > 0 && - [...dataRefIds] - .sort() - .map(id => )} -
    -
    + [...dataRefIds].sort().map(id => )} + {!enabled && } + + -
    + ); } From 899530efb52bf9b00eedb26ab0ab72a8eeb9c12b Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 1 Nov 2023 18:18:42 +0100 Subject: [PATCH 192/275] plugins: add visualizer Signed-off-by: Patrik Oldsberg --- packages/app-next/package.json | 1 + packages/app-next/src/App.tsx | 4 +- packages/app-next/src/plugins/index.ts | 19 -------- plugins/visualizer/.eslintrc.js | 1 + plugins/visualizer/README.md | 3 ++ plugins/visualizer/api-report.md | 13 +++++ plugins/visualizer/catalog-info.yaml | 10 ++++ plugins/visualizer/package.json | 47 +++++++++++++++++++ .../AppVisualizerPage/AppVisualizerPage.tsx | 0 .../AppVisualizerPage/GraphVisualizer.tsx | 0 .../AppVisualizerPage/TextVisualizer.tsx | 0 .../components/AppVisualizerPage/index.ts | 0 .../visualizer/src}/index.ts | 2 +- .../visualizer/src}/plugin.tsx | 0 yarn.lock | 22 +++++++++ 15 files changed, 100 insertions(+), 22 deletions(-) delete mode 100644 packages/app-next/src/plugins/index.ts create mode 100644 plugins/visualizer/.eslintrc.js create mode 100644 plugins/visualizer/README.md create mode 100644 plugins/visualizer/api-report.md create mode 100644 plugins/visualizer/catalog-info.yaml create mode 100644 plugins/visualizer/package.json rename {packages/app-next/src/plugins/app-visualizer => plugins/visualizer/src}/components/AppVisualizerPage/AppVisualizerPage.tsx (100%) rename {packages/app-next/src/plugins/app-visualizer => plugins/visualizer/src}/components/AppVisualizerPage/GraphVisualizer.tsx (100%) rename {packages/app-next/src/plugins/app-visualizer => plugins/visualizer/src}/components/AppVisualizerPage/TextVisualizer.tsx (100%) rename {packages/app-next/src/plugins/app-visualizer => plugins/visualizer/src}/components/AppVisualizerPage/index.ts (100%) rename {packages/app-next/src/plugins/app-visualizer => plugins/visualizer/src}/index.ts (91%) rename {packages/app-next/src/plugins/app-visualizer => plugins/visualizer/src}/plugin.tsx (100%) diff --git a/packages/app-next/package.json b/packages/app-next/package.json index 4bbc4fe5be..d6145b5286 100644 --- a/packages/app-next/package.json +++ b/packages/app-next/package.json @@ -75,6 +75,7 @@ "@backstage/plugin-techdocs-react": "workspace:^", "@backstage/plugin-todo": "workspace:^", "@backstage/plugin-user-settings": "workspace:^", + "@backstage/plugin-visualizer": "workspace:^", "@backstage/theme": "workspace:^", "@circleci/backstage-plugin": "^0.1.1", "@material-ui/core": "^4.12.2", diff --git a/packages/app-next/src/App.tsx b/packages/app-next/src/App.tsx index 09f454f302..112532cee2 100644 --- a/packages/app-next/src/App.tsx +++ b/packages/app-next/src/App.tsx @@ -32,7 +32,7 @@ import { createExtensionOverrides, } from '@backstage/frontend-plugin-api'; import techdocsPlugin from '@backstage/plugin-techdocs/alpha'; -import { plugins } from './plugins'; +import appVisualizerPlugin from '@backstage/plugin-visualizer'; import { homePage } from './HomePage'; import { convertLegacyApp } from '@backstage/core-compat-api'; import { FlatRoutes } from '@backstage/core-app-api'; @@ -124,7 +124,7 @@ const app = createApp({ techdocsPlugin, userSettingsPlugin, homePlugin, - ...plugins, + appVisualizerPlugin, ...collectedLegacyPlugins, createExtensionOverrides({ extensions: [ diff --git a/packages/app-next/src/plugins/index.ts b/packages/app-next/src/plugins/index.ts deleted file mode 100644 index baafcde889..0000000000 --- a/packages/app-next/src/plugins/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { appVisualizerPlugin } from './app-visualizer'; - -export const plugins = [appVisualizerPlugin]; diff --git a/plugins/visualizer/.eslintrc.js b/plugins/visualizer/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/visualizer/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/visualizer/README.md b/plugins/visualizer/README.md new file mode 100644 index 0000000000..dd6f081a18 --- /dev/null +++ b/plugins/visualizer/README.md @@ -0,0 +1,3 @@ +# @backstage/plugin-visualizer + +A plugin to help visualize the structure of your Backstage app. diff --git a/plugins/visualizer/api-report.md b/plugins/visualizer/api-report.md new file mode 100644 index 0000000000..0cd9eface0 --- /dev/null +++ b/plugins/visualizer/api-report.md @@ -0,0 +1,13 @@ +## API Report File for "@backstage/plugin-visualizer" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackstagePlugin } from '@backstage/frontend-plugin-api'; + +// @public (undocumented) +const visualizerPlugin: BackstagePlugin<{}, {}>; +export default visualizerPlugin; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/visualizer/catalog-info.yaml b/plugins/visualizer/catalog-info.yaml new file mode 100644 index 0000000000..f9cedddf87 --- /dev/null +++ b/plugins/visualizer/catalog-info.yaml @@ -0,0 +1,10 @@ +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: backstage-plugin-visualizer + title: '@backstage/plugin-visualizer' + description: Visualizes the Backstage app structure +spec: + lifecycle: experimental + type: backstage-frontend-plugin + owner: maintainers diff --git a/plugins/visualizer/package.json b/plugins/visualizer/package.json new file mode 100644 index 0000000000..afcbd81951 --- /dev/null +++ b/plugins/visualizer/package.json @@ -0,0 +1,47 @@ +{ + "name": "@backstage/plugin-visualizer", + "description": "Visualizes the Backstage app structure", + "private": true, + "version": "0.0.0", + "publishConfig": { + "access": "public" + }, + "backstage": { + "role": "frontend-plugin" + }, + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "sideEffects": false, + "scripts": { + "build": "backstage-cli package build", + "start": "backstage-cli package start", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack", + "clean": "backstage-cli package clean" + }, + "dependencies": { + "@backstage/core-components": "workspace:^", + "@backstage/core-plugin-api": "workspace:^", + "@backstage/frontend-plugin-api": "workspace:^", + "@backstage/theme": "workspace:^", + "@material-ui/core": "^4.12.2", + "@material-ui/icons": "^4.9.1", + "@material-ui/lab": "4.0.0-alpha.61", + "@types/react": "^16.13.1 || ^17.0.0", + "react-use": "^17.2.4" + }, + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "devDependencies": { + "@backstage/cli": "workspace:^" + }, + "files": [ + "dist" + ] +} diff --git a/packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage/AppVisualizerPage.tsx b/plugins/visualizer/src/components/AppVisualizerPage/AppVisualizerPage.tsx similarity index 100% rename from packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage/AppVisualizerPage.tsx rename to plugins/visualizer/src/components/AppVisualizerPage/AppVisualizerPage.tsx diff --git a/packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage/GraphVisualizer.tsx b/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx similarity index 100% rename from packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage/GraphVisualizer.tsx rename to plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx diff --git a/packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage/TextVisualizer.tsx b/plugins/visualizer/src/components/AppVisualizerPage/TextVisualizer.tsx similarity index 100% rename from packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage/TextVisualizer.tsx rename to plugins/visualizer/src/components/AppVisualizerPage/TextVisualizer.tsx diff --git a/packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage/index.ts b/plugins/visualizer/src/components/AppVisualizerPage/index.ts similarity index 100% rename from packages/app-next/src/plugins/app-visualizer/components/AppVisualizerPage/index.ts rename to plugins/visualizer/src/components/AppVisualizerPage/index.ts diff --git a/packages/app-next/src/plugins/app-visualizer/index.ts b/plugins/visualizer/src/index.ts similarity index 91% rename from packages/app-next/src/plugins/app-visualizer/index.ts rename to plugins/visualizer/src/index.ts index 63fd16c520..60e8ced455 100644 --- a/packages/app-next/src/plugins/app-visualizer/index.ts +++ b/plugins/visualizer/src/index.ts @@ -14,4 +14,4 @@ * limitations under the License. */ -export { appVisualizerPlugin } from './plugin'; +export { appVisualizerPlugin as default } from './plugin'; diff --git a/packages/app-next/src/plugins/app-visualizer/plugin.tsx b/plugins/visualizer/src/plugin.tsx similarity index 100% rename from packages/app-next/src/plugins/app-visualizer/plugin.tsx rename to plugins/visualizer/src/plugin.tsx diff --git a/yarn.lock b/yarn.lock index 4719742e16..624293289b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10068,6 +10068,27 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-visualizer@workspace:^, @backstage/plugin-visualizer@workspace:plugins/visualizer": + version: 0.0.0-use.local + resolution: "@backstage/plugin-visualizer@workspace:plugins/visualizer" + dependencies: + "@backstage/cli": "workspace:^" + "@backstage/core-components": "workspace:^" + "@backstage/core-plugin-api": "workspace:^" + "@backstage/frontend-plugin-api": "workspace:^" + "@backstage/theme": "workspace:^" + "@material-ui/core": ^4.12.2 + "@material-ui/icons": ^4.9.1 + "@material-ui/lab": 4.0.0-alpha.61 + "@types/react": ^16.13.1 || ^17.0.0 + react-use: ^17.2.4 + peerDependencies: + react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 + languageName: unknown + linkType: soft + "@backstage/plugin-xcmetrics@workspace:plugins/xcmetrics": version: 0.0.0-use.local resolution: "@backstage/plugin-xcmetrics@workspace:plugins/xcmetrics" @@ -26658,6 +26679,7 @@ __metadata: "@backstage/plugin-techdocs-react": "workspace:^" "@backstage/plugin-todo": "workspace:^" "@backstage/plugin-user-settings": "workspace:^" + "@backstage/plugin-visualizer": "workspace:^" "@backstage/test-utils": "workspace:^" "@backstage/theme": "workspace:^" "@circleci/backstage-plugin": ^0.1.1 From dacdfa401a90195aa14877cbf6fd961d9943f10c Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 2 Nov 2023 01:00:11 +0100 Subject: [PATCH 193/275] visualizer: add nav item Signed-off-by: Patrik Oldsberg --- plugins/visualizer/src/index.ts | 2 +- plugins/visualizer/src/plugin.tsx | 23 ++++++++++++++++++----- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/plugins/visualizer/src/index.ts b/plugins/visualizer/src/index.ts index 60e8ced455..b91a06c569 100644 --- a/plugins/visualizer/src/index.ts +++ b/plugins/visualizer/src/index.ts @@ -14,4 +14,4 @@ * limitations under the License. */ -export { appVisualizerPlugin as default } from './plugin'; +export { visualizerPlugin as default } from './plugin'; diff --git a/plugins/visualizer/src/plugin.tsx b/plugins/visualizer/src/plugin.tsx index c39cb9a6c3..216c1f8ee2 100644 --- a/plugins/visualizer/src/plugin.tsx +++ b/plugins/visualizer/src/plugin.tsx @@ -15,19 +15,32 @@ */ import { + createNavItemExtension, createPageExtension, createPlugin, + createRouteRef, } from '@backstage/frontend-plugin-api'; +import VisualizerIcon from '@material-ui/icons/Visibility'; import React from 'react'; -const appVisualizerPage = createPageExtension({ - id: 'plugin.app-visualizer.page', +const rootRouteRef = createRouteRef(); + +const visualizerPage = createPageExtension({ + id: 'plugin.visualizer.page', defaultPath: '/visualizer', + routeRef: rootRouteRef, loader: () => import('./components/AppVisualizerPage').then(m => ), }); -export const appVisualizerPlugin = createPlugin({ - id: 'app-visualizer', - extensions: [appVisualizerPage], +export const visualizerPageSidebarItem = createNavItemExtension({ + id: 'plugin.visualizer.nav.index', + title: 'Visualizer', + icon: VisualizerIcon, + routeRef: rootRouteRef, +}); + +export const visualizerPlugin = createPlugin({ + id: 'visualizer', + extensions: [visualizerPage, visualizerPageSidebarItem], }); From 1300459235020645deedf5f4a36f73e94bbcec46 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 2 Nov 2023 14:15:33 +0100 Subject: [PATCH 194/275] visualizer: always select entire extension ID Signed-off-by: Patrik Oldsberg --- .../src/components/AppVisualizerPage/GraphVisualizer.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx b/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx index f8b9ae2d72..4f98e890f5 100644 --- a/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx +++ b/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx @@ -99,6 +99,9 @@ const useStyles = makeStyles(theme => ({ borderTopRightRadius: theme.shape.borderRadius, borderBottomRightRadius: theme.shape.borderRadius, }, + extensionHeaderId: { + userSelect: 'all', + }, extensionHeaderOutputs: { display: 'flex', flexFlow: 'row nowrap', @@ -223,7 +226,9 @@ function Extension(props: { node: AppNode }) { }> - {node.spec.id} + + {node.spec.id} + {dataRefIds && From 29ad231a22e8f322b8cd91122aca005d8b1f6f34 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 2 Nov 2023 14:16:01 +0100 Subject: [PATCH 195/275] visualizer: do not reorder extensions Signed-off-by: Patrik Oldsberg --- .../src/components/AppVisualizerPage/GraphVisualizer.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx b/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx index 4f98e890f5..ae78611d2e 100644 --- a/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx +++ b/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx @@ -170,9 +170,7 @@ function Attachments(props: { {[...attachments.entries()] .sort(([a], [b]) => a.localeCompare(b)) - .map(([key, v]) => { - const children = v.sort((a, b) => a.spec.id.localeCompare(b.spec.id)); - + .map(([key, children]) => { return ( From 5b290176493ecd1d346f80b7903a16252ecb0ec2 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 2 Nov 2023 14:43:12 +0100 Subject: [PATCH 196/275] visualizer: render route paths and links Signed-off-by: Patrik Oldsberg --- .../AppVisualizerPage/GraphVisualizer.tsx | 95 ++++++++++++++++--- 1 file changed, 81 insertions(+), 14 deletions(-) diff --git a/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx b/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx index ae78611d2e..de043d71ca 100644 --- a/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx +++ b/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx @@ -14,7 +14,14 @@ * limitations under the License. */ -import { AppNode, AppTree } from '@backstage/frontend-plugin-api'; +import { + AppNode, + AppTree, + ExtensionDataRef, + RouteRef, + coreExtensionData, + useRouteRef, +} from '@backstage/frontend-plugin-api'; import Box from '@material-ui/core/Box'; import Tooltip from '@material-ui/core/Tooltip'; import Typography from '@material-ui/core/Typography'; @@ -23,6 +30,7 @@ import { Theme, makeStyles } from '@material-ui/core/styles'; import InputIcon from '@material-ui/icons/InputSharp'; import DisabledIcon from '@material-ui/icons/NotInterestedSharp'; import React from 'react'; +import { Link } from 'react-router-dom'; function createOutputColorGenerator(availableColors: string[]) { const map = new Map(); @@ -139,17 +147,75 @@ const useStyles = makeStyles(theme => ({ }, })); -function Output(props: { id: string }) { - const { id } = props; +const useOutputStyles = makeStyles(theme => ({ + output: ({ color }: { color: string }) => ({ + padding: `0 10px`, + height: 20, + borderRadius: 10, + color: theme.palette.getContrastText(color), + backgroundColor: color, + }), +})); + +function getFullPath(node?: AppNode): string { + if (!node) { + return ''; + } + const parent = node.edges.attachedTo?.node; + const part = node.instance?.getData(coreExtensionData.routePath); + if (!part) { + return getFullPath(parent); + } + return getFullPath(parent) + part; +} + +function OutputLink(props: { + dataRef: ExtensionDataRef; + node: AppNode; + className: string; +}) { + const routeRef = props.node.instance?.getData(coreExtensionData.routeRef); + + let link: string | undefined = undefined; + try { + link = useRouteRef(routeRef as RouteRef)(); + } catch { + /* ignore */ + } + + return ( + {props.dataRef.id}}> + + {link ? link : null} + + + ); +} + +function Output(props: { dataRef: ExtensionDataRef; node: AppNode }) { + const { dataRef, node } = props; + const { id } = dataRef; + const instance = node.instance!; + + const classes = useOutputStyles({ color: getOutputColor(id) }); + + if (id === coreExtensionData.routePath.id) { + return ( + {getFullPath(node)}}> + + {String(instance.getData(dataRef))} + + + ); + } + + if (id === coreExtensionData.routeRef.id) { + return ; + } return ( {id}}> - + ); } @@ -217,8 +283,7 @@ function Extension(props: { node: AppNode }) { const enabled = Boolean(node.instance); const classes = useStyles({ enabled }); - const dataRefIds = - node.instance && [...node.instance.getDataRefs()].map(r => r.id); + const dataRefs = node.instance && [...node.instance.getDataRefs()]; return ( @@ -229,9 +294,11 @@ function Extension(props: { node: AppNode }) { - {dataRefIds && - dataRefIds.length > 0 && - [...dataRefIds].sort().map(id => )} + {dataRefs && + dataRefs.length > 0 && + dataRefs + .sort((a, b) => a.id.localeCompare(b.id)) + .map(ref => )} {!enabled && } From defd9b3a2858003cbc6cb13c9d4feb59603c5c7a Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 3 Nov 2023 10:25:33 +0100 Subject: [PATCH 197/275] visualizer: use fixed colors for core data types Signed-off-by: Patrik Oldsberg --- .../AppVisualizerPage/GraphVisualizer.tsx | 43 +++++++++++-------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx b/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx index de043d71ca..e047bc498f 100644 --- a/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx +++ b/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx @@ -32,11 +32,17 @@ import DisabledIcon from '@material-ui/icons/NotInterestedSharp'; import React from 'react'; import { Link } from 'react-router-dom'; -function createOutputColorGenerator(availableColors: string[]) { +function createOutputColorGenerator( + colorMap: { [extDataId: string]: string }, + availableColors: string[], +) { const map = new Map(); let i = 0; return function getOutputColor(id: string) { + if (id in colorMap) { + return colorMap[id]; + } let color = map.get(id); if (color) { return color; @@ -51,22 +57,25 @@ function createOutputColorGenerator(availableColors: string[]) { }; } -const getOutputColor = createOutputColorGenerator([ - colors.green[500], - colors.blue[500], - colors.yellow[500], - colors.purple[500], - colors.orange[500], - colors.red[500], - colors.lime[500], - colors.green[200], - colors.blue[200], - colors.yellow[200], - colors.purple[200], - colors.orange[200], - colors.red[200], - colors.lime[200], -]); +const getOutputColor = createOutputColorGenerator( + { + [coreExtensionData.reactElement.id]: colors.green[500], + [coreExtensionData.routePath.id]: colors.yellow[500], + [coreExtensionData.routeRef.id]: colors.purple[500], + [coreExtensionData.apiFactory.id]: colors.blue[500], + [coreExtensionData.theme.id]: colors.lime[500], + [coreExtensionData.navTarget.id]: colors.orange[500], + }, + [ + colors.blue[200], + colors.orange[200], + colors.green[200], + colors.red[200], + colors.yellow[200], + colors.purple[200], + colors.lime[200], + ], +); interface StyleProps { enabled: boolean; From 94295786267b87b677e067a1564a523dc1f90618 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 3 Nov 2023 10:28:02 +0100 Subject: [PATCH 198/275] visualizer: styles cleanup Signed-off-by: Patrik Oldsberg --- .../src/components/AppVisualizerPage/GraphVisualizer.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx b/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx index e047bc498f..f4945a0534 100644 --- a/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx +++ b/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx @@ -104,7 +104,6 @@ const useStyles = makeStyles(theme => ({ }, extensionHeader: { display: 'flex', - flexFlow: 'row nowrap', alignItems: 'center', width: 'fit-content', @@ -121,7 +120,6 @@ const useStyles = makeStyles(theme => ({ }, extensionHeaderOutputs: { display: 'flex', - flexFlow: 'row nowrap', alignItems: 'center', marginLeft: theme.spacing(1), gap: theme.spacing(1), @@ -134,7 +132,6 @@ const useStyles = makeStyles(theme => ({ }, attachmentsInputTitle: { display: 'flex', - flexFlow: 'row nowrap', alignItems: 'center', width: 'fit-content', padding: theme.spacing(1), @@ -148,7 +145,7 @@ const useStyles = makeStyles(theme => ({ }, attachmentsInputChildren: { display: 'flex', - flexFlow: 'column nowrap', + flexDirection: 'column', alignItems: 'flex-start', gap: theme.spacing(0.5), marginLeft: theme.spacing(1), From 8c71296cc48acc7e059a86a074a79f46a1f5d1ab Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 3 Nov 2023 10:56:37 +0100 Subject: [PATCH 199/275] visualizer: add legend Signed-off-by: Patrik Oldsberg --- .../AppVisualizerPage/GraphVisualizer.tsx | 58 ++++++++++++++++--- 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx b/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx index f4945a0534..327c2d226b 100644 --- a/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx +++ b/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx @@ -23,6 +23,7 @@ import { useRouteRef, } from '@backstage/frontend-plugin-api'; import Box from '@material-ui/core/Box'; +import Paper from '@material-ui/core/Paper'; import Tooltip from '@material-ui/core/Tooltip'; import Typography from '@material-ui/core/Typography'; import * as colors from '@material-ui/core/colors'; @@ -177,10 +178,10 @@ function getFullPath(node?: AppNode): string { function OutputLink(props: { dataRef: ExtensionDataRef; - node: AppNode; + node?: AppNode; className: string; }) { - const routeRef = props.node.instance?.getData(coreExtensionData.routeRef); + const routeRef = props.node?.instance?.getData(coreExtensionData.routeRef); let link: string | undefined = undefined; try { @@ -198,10 +199,10 @@ function OutputLink(props: { ); } -function Output(props: { dataRef: ExtensionDataRef; node: AppNode }) { +function Output(props: { dataRef: ExtensionDataRef; node?: AppNode }) { const { dataRef, node } = props; const { id } = dataRef; - const instance = node.instance!; + const instance = node?.instance; const classes = useOutputStyles({ color: getOutputColor(id) }); @@ -209,7 +210,7 @@ function Output(props: { dataRef: ExtensionDataRef; node: AppNode }) { return ( {getFullPath(node)}}> - {String(instance.getData(dataRef))} + {String(instance?.getData(dataRef) ?? '')} ); @@ -313,10 +314,51 @@ function Extension(props: { node: AppNode }) { ); } -export function GraphVisualizer({ tree }: { tree: AppTree }) { +const legendMap = { + 'React Element': coreExtensionData.reactElement, + 'Utility API': coreExtensionData.apiFactory, + 'Route Path': coreExtensionData.routePath, + 'Route Ref': coreExtensionData.routeRef, + 'Nav Target': coreExtensionData.navTarget, + Theme: coreExtensionData.theme, +}; + +function Legend() { return ( - - + + {Object.entries(legendMap).map(([label, dataRef]) => ( + + + {label} + + ))} + + ); +} + +export function GraphVisualizer({ tree }: { tree: AppTree }) { + return ( + + + + + + + + ); } From 32f03b69760886035a40ff241cc5a08a8b1267b6 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 4 Nov 2023 14:38:43 +0100 Subject: [PATCH 200/275] visualizer: depth based borders Signed-off-by: Patrik Oldsberg --- .../AppVisualizerPage/GraphVisualizer.tsx | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx b/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx index 327c2d226b..89112b2f4c 100644 --- a/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx +++ b/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx @@ -27,7 +27,7 @@ import Paper from '@material-ui/core/Paper'; import Tooltip from '@material-ui/core/Tooltip'; import Typography from '@material-ui/core/Typography'; import * as colors from '@material-ui/core/colors'; -import { Theme, makeStyles } from '@material-ui/core/styles'; +import { makeStyles } from '@material-ui/core/styles'; import InputIcon from '@material-ui/icons/InputSharp'; import DisabledIcon from '@material-ui/icons/NotInterestedSharp'; import React from 'react'; @@ -80,11 +80,7 @@ const getOutputColor = createOutputColorGenerator( interface StyleProps { enabled: boolean; -} - -function borderColor(theme: Theme) { - return ({ enabled }: StyleProps) => - enabled ? theme.palette.primary.main : theme.palette.divider; + depth: number; } const config = { @@ -95,7 +91,8 @@ const useStyles = makeStyles(theme => ({ extension: { borderLeftWidth: theme.spacing(config.borderWidth), borderLeftStyle: 'solid', - borderLeftColor: borderColor(theme), + borderLeftColor: ({ depth }: StyleProps) => + colors.grey[(700 - (depth % 6) * 100) as keyof typeof colors.grey], cursor: 'pointer', '&:hover $extensionHeader': { @@ -139,7 +136,8 @@ const useStyles = makeStyles(theme => ({ borderTopWidth: theme.spacing(config.borderWidth), borderTopStyle: 'solid', - borderTopColor: borderColor(theme), + borderTopColor: ({ depth }: StyleProps) => + colors.grey[(700 - (depth % 6) * 100) as keyof typeof colors.grey], }, attachmentsInputName: { marginLeft: theme.spacing(1), @@ -230,10 +228,11 @@ function Output(props: { dataRef: ExtensionDataRef; node?: AppNode }) { function Attachments(props: { attachments: ReadonlyMap; enabled: boolean; + depth: number; }) { - const { attachments, enabled } = props; + const { attachments, enabled, depth } = props; - const classes = useStyles({ enabled }); + const classes = useStyles({ enabled, depth }); if (attachments.size === 0) { return null; @@ -254,7 +253,7 @@ function Attachments(props: { {children.map(node => ( - + ))} @@ -284,11 +283,11 @@ function ExtensionTooltip(props: { node: AppNode }) { ); } -function Extension(props: { node: AppNode }) { - const { node } = props; +function Extension(props: { node: AppNode; depth: number }) { + const { node, depth } = props; const enabled = Boolean(node.instance); - const classes = useStyles({ enabled }); + const classes = useStyles({ enabled, depth }); const dataRefs = node.instance && [...node.instance.getDataRefs()]; @@ -309,7 +308,11 @@ function Extension(props: { node: AppNode }) { {!enabled && } - + ); } @@ -353,7 +356,7 @@ export function GraphVisualizer({ tree }: { tree: AppTree }) { return ( - + From d7a24cb4f9f0aa5aaa5ca38f81beec300016b9a8 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 4 Nov 2023 20:02:49 +0100 Subject: [PATCH 201/275] visualizer: tweak spacing a bit Signed-off-by: Patrik Oldsberg --- .../src/components/AppVisualizerPage/GraphVisualizer.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx b/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx index 89112b2f4c..3b6f2c9c90 100644 --- a/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx +++ b/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx @@ -122,7 +122,11 @@ const useStyles = makeStyles(theme => ({ marginLeft: theme.spacing(1), gap: theme.spacing(1), }, - attachments: {}, + attachments: { + gap: theme.spacing(2), + display: 'flex', + flexDirection: 'column', + }, attachmentsInput: { '&:first-child $attachmentsInputTitle': { borderTop: 0, From db79a2026d89aec500e627a5e2fbcb6158936259 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 4 Nov 2023 20:58:27 +0100 Subject: [PATCH 202/275] visualizer: pass full node to attachments Signed-off-by: Patrik Oldsberg --- .../components/AppVisualizerPage/GraphVisualizer.tsx | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx b/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx index 3b6f2c9c90..52d090af48 100644 --- a/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx +++ b/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx @@ -230,11 +230,12 @@ function Output(props: { dataRef: ExtensionDataRef; node?: AppNode }) { } function Attachments(props: { - attachments: ReadonlyMap; + node: AppNode; enabled: boolean; depth: number; }) { - const { attachments, enabled, depth } = props; + const { node, enabled, depth } = props; + const { attachments } = node.edges; const classes = useStyles({ enabled, depth }); @@ -312,11 +313,7 @@ function Extension(props: { node: AppNode; depth: number }) { {!enabled && } - + ); } From 4b3d0ec9e7aaa21d251cf4ad92a1679501e96faf Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 4 Nov 2023 21:23:06 +0100 Subject: [PATCH 203/275] visualizer: initial tree visualizer Signed-off-by: Patrik Oldsberg --- .../AppVisualizerPage/AppVisualizerPage.tsx | 2 + .../AppVisualizerPage/TreeVisualizer.tsx | 57 +++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 plugins/visualizer/src/components/AppVisualizerPage/TreeVisualizer.tsx diff --git a/plugins/visualizer/src/components/AppVisualizerPage/AppVisualizerPage.tsx b/plugins/visualizer/src/components/AppVisualizerPage/AppVisualizerPage.tsx index ec6145a1af..78ace296b4 100644 --- a/plugins/visualizer/src/components/AppVisualizerPage/AppVisualizerPage.tsx +++ b/plugins/visualizer/src/components/AppVisualizerPage/AppVisualizerPage.tsx @@ -21,6 +21,7 @@ import Box from '@material-ui/core/Box'; import React, { useState } from 'react'; import { GraphVisualizer } from './GraphVisualizer'; import { TextVisualizer } from './TextVisualizer'; +import { TreeVisualizer } from './TreeVisualizer'; export function AppVisualizerPage() { const appTreeApi = useApi(appTreeApiRef); @@ -29,6 +30,7 @@ export function AppVisualizerPage() { const tabs = [ { id: 'graph', label: 'Graph', element: }, + { id: 'tree', label: 'Tree', element: }, { id: 'text', label: 'Text', element: }, ]; diff --git a/plugins/visualizer/src/components/AppVisualizerPage/TreeVisualizer.tsx b/plugins/visualizer/src/components/AppVisualizerPage/TreeVisualizer.tsx new file mode 100644 index 0000000000..1260da3c32 --- /dev/null +++ b/plugins/visualizer/src/components/AppVisualizerPage/TreeVisualizer.tsx @@ -0,0 +1,57 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + DependencyGraph, + DependencyGraphTypes, +} from '@backstage/core-components'; +import { AppTree } from '@backstage/frontend-plugin-api'; +import Box from '@material-ui/core/Box'; +import { useMemo } from 'react'; + +function resolveGraphData(tree: AppTree) { + const nodes = [...tree.nodes.values()] + .filter(n => n.instance) + .map(n => ({ ...n, id: n.spec.id })); + return { + nodes, + edges: nodes + .filter(n => n.edges.attachedTo) + .map(n => ({ + from: n.spec.id, + to: n.edges.attachedTo!.node.spec.id, + label: n.edges.attachedTo!.input, + })), + }; +} + +export function TreeVisualizer({ tree }: { tree: AppTree }) { + const graphData = useMemo(() => resolveGraphData(tree), [tree]); + + return ( + + + + ); +} From 5ad1a062e32ca76ee7d9fe184d2a1903a2641e03 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 4 Nov 2023 21:49:16 +0100 Subject: [PATCH 204/275] visualizer: split inputs to separate nodes in tree Signed-off-by: Patrik Oldsberg --- .../AppVisualizerPage/TreeVisualizer.tsx | 120 ++++++++++++++++-- 1 file changed, 106 insertions(+), 14 deletions(-) diff --git a/plugins/visualizer/src/components/AppVisualizerPage/TreeVisualizer.tsx b/plugins/visualizer/src/components/AppVisualizerPage/TreeVisualizer.tsx index 1260da3c32..d405e1e164 100644 --- a/plugins/visualizer/src/components/AppVisualizerPage/TreeVisualizer.tsx +++ b/plugins/visualizer/src/components/AppVisualizerPage/TreeVisualizer.tsx @@ -18,26 +18,117 @@ import { DependencyGraph, DependencyGraphTypes, } from '@backstage/core-components'; -import { AppTree } from '@backstage/frontend-plugin-api'; +import { AppNode, AppTree } from '@backstage/frontend-plugin-api'; import Box from '@material-ui/core/Box'; -import { useMemo } from 'react'; +import { makeStyles } from '@material-ui/core/styles'; +import { useLayoutEffect, useMemo, useRef, useState } from 'react'; -function resolveGraphData(tree: AppTree) { +type NodeType = + | ({ type: 'node'; id: string } & AppNode) + | { type: 'input'; id: string; name: string }; + +function inputId({ node, input }: { node: AppNode; input: string }) { + return `${node.spec.id}$$${input}`; +} + +function resolveGraphData(tree: AppTree): { + nodes: NodeType[]; + edges: { from: string; to: string }[]; +} { const nodes = [...tree.nodes.values()] - .filter(n => n.instance) - .map(n => ({ ...n, id: n.spec.id })); + .filter(node => node.instance) + .map(node => ({ ...node, id: node.spec.id, type: 'node' as const })); + return { - nodes, - edges: nodes - .filter(n => n.edges.attachedTo) - .map(n => ({ - from: n.spec.id, - to: n.edges.attachedTo!.node.spec.id, - label: n.edges.attachedTo!.input, - })), + nodes: [ + ...nodes, + ...nodes.flatMap(node => + [...node.edges.attachments.keys()].map(input => ({ + id: inputId({ node, input }), + type: 'input' as const, + name: input, + })), + ), + ], + edges: [ + ...nodes + .filter(node => node.edges.attachedTo) + .map(node => ({ + from: inputId(node.edges.attachedTo!), + to: node.spec.id, + })), + ...nodes.flatMap(node => + [...node.edges.attachments.keys()].map(input => ({ + from: node.spec.id, + to: inputId({ node, input }), + })), + ), + ], }; } +const useStyles = makeStyles(theme => ({ + node: { + fill: (node: NodeType) => + node.type === 'node' + ? theme.palette.primary.light + : theme.palette.grey[500], + stroke: theme.palette.primary.light, + }, + text: { + fill: theme.palette.primary.contrastText, + }, +})); + +/** @public */ +export function Node(props: { node: NodeType }) { + const { node } = props; + const classes = useStyles(node); + const [width, setWidth] = useState(0); + const [height, setHeight] = useState(0); + const idRef = useRef(null); + + useLayoutEffect(() => { + // set the width to the length of the ID + if (idRef.current) { + let { height: renderedHeight, width: renderedWidth } = + idRef.current.getBBox(); + renderedHeight = Math.round(renderedHeight); + renderedWidth = Math.round(renderedWidth); + + if (renderedHeight !== height || renderedWidth !== width) { + setWidth(renderedWidth); + setHeight(renderedHeight); + } + } + }, [width, height]); + + const padding = 10; + const paddedWidth = width + padding * 2; + const paddedHeight = height + padding * 2; + + return ( + + + + {node.type === 'node' ? node.id : node.name} + + + ); +} + export function TreeVisualizer({ tree }: { tree: AppTree }) { const graphData = useMemo(() => resolveGraphData(tree), [tree]); @@ -50,7 +141,8 @@ export function TreeVisualizer({ tree }: { tree: AppTree }) { nodeMargin={10} edgeMargin={30} rankMargin={100} - direction={DependencyGraphTypes.Direction.BOTTOM_TOP} + renderNode={Node} + direction={DependencyGraphTypes.Direction.TOP_BOTTOM} /> ); From 389e61a49803dd6ffe22247822c82ba6b979e7e9 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 4 Nov 2023 22:09:22 +0100 Subject: [PATCH 205/275] visualizer: cleaner tree Signed-off-by: Patrik Oldsberg --- .../AppVisualizerPage/TreeVisualizer.tsx | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/plugins/visualizer/src/components/AppVisualizerPage/TreeVisualizer.tsx b/plugins/visualizer/src/components/AppVisualizerPage/TreeVisualizer.tsx index d405e1e164..f38acf1379 100644 --- a/plugins/visualizer/src/components/AppVisualizerPage/TreeVisualizer.tsx +++ b/plugins/visualizer/src/components/AppVisualizerPage/TreeVisualizer.tsx @@ -31,6 +31,23 @@ function inputId({ node, input }: { node: AppNode; input: string }) { return `${node.spec.id}$$${input}`; } +function trimNodeId(id: string) { + let newId = id; + if (newId.startsWith('apis.')) { + newId = newId.slice('apis.'.length); + } + if (newId.startsWith('plugin.')) { + newId = newId.slice('plugin.'.length); + } + if (newId.startsWith('catalog.filter.entity.')) { + newId = newId.slice('catalog.filter.entity.'.length); + } + if (newId.endsWith('.nav.index')) { + newId = newId.slice(0, -'.nav.index'.length); + } + return newId; +} + function resolveGraphData(tree: AppTree): { nodes: NodeType[]; edges: { from: string; to: string }[]; @@ -73,7 +90,10 @@ const useStyles = makeStyles(theme => ({ node.type === 'node' ? theme.palette.primary.light : theme.palette.grey[500], - stroke: theme.palette.primary.light, + stroke: (node: NodeType) => + node.type === 'node' + ? theme.palette.primary.main + : theme.palette.grey[600], }, text: { fill: theme.palette.primary.contrastText, @@ -123,7 +143,7 @@ export function Node(props: { node: NodeType }) { textAnchor="middle" alignmentBaseline="middle" > - {node.type === 'node' ? node.id : node.name} + {node.type === 'node' ? trimNodeId(node.id) : node.name} ); @@ -139,9 +159,11 @@ export function TreeVisualizer({ tree }: { tree: AppTree }) { style={{ height: '100%', width: '100%' }} {...graphData} nodeMargin={10} - edgeMargin={30} - rankMargin={100} + rankMargin={50} + paddingX={50} renderNode={Node} + align={DependencyGraphTypes.Alignment.DOWN_RIGHT} + ranker={DependencyGraphTypes.Ranker.TIGHT_TREE} direction={DependencyGraphTypes.Direction.TOP_BOTTOM} /> From cbd836aef45e7c2cd97a38c1308d04ba0f8945bc Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 4 Nov 2023 22:19:54 +0100 Subject: [PATCH 206/275] visualizer: switch to routed tabs Signed-off-by: Patrik Oldsberg --- .../AppVisualizerPage/AppVisualizerPage.tsx | 70 ++++++++++++++++--- 1 file changed, 61 insertions(+), 9 deletions(-) diff --git a/plugins/visualizer/src/components/AppVisualizerPage/AppVisualizerPage.tsx b/plugins/visualizer/src/components/AppVisualizerPage/AppVisualizerPage.tsx index 78ace296b4..cc7dca24f4 100644 --- a/plugins/visualizer/src/components/AppVisualizerPage/AppVisualizerPage.tsx +++ b/plugins/visualizer/src/components/AppVisualizerPage/AppVisualizerPage.tsx @@ -18,29 +18,81 @@ import { Content, Header, HeaderTabs, Page } from '@backstage/core-components'; import { useApi } from '@backstage/core-plugin-api'; import { appTreeApiRef } from '@backstage/frontend-plugin-api'; import Box from '@material-ui/core/Box'; -import React, { useState } from 'react'; +import React, { useCallback, useEffect, useMemo } from 'react'; import { GraphVisualizer } from './GraphVisualizer'; import { TextVisualizer } from './TextVisualizer'; import { TreeVisualizer } from './TreeVisualizer'; +import { + matchRoutes, + useLocation, + useNavigate, + useParams, + useRoutes, +} from 'react-router-dom'; export function AppVisualizerPage() { const appTreeApi = useApi(appTreeApiRef); const { tree } = appTreeApi.getTree(); - const [tab, setTab] = useState(0); - const tabs = [ - { id: 'graph', label: 'Graph', element: }, - { id: 'tree', label: 'Tree', element: }, - { id: 'text', label: 'Text', element: }, - ]; + const tabs = useMemo( + () => [ + { + id: 'graph', + path: 'graph', + label: 'Graph', + element: , + }, + { + id: 'tree', + path: 'tree', + label: 'Tree', + element: , + }, + { + id: 'text', + path: 'text', + label: 'Text', + element: , + }, + ], + [tree], + ); + + const location = useLocation(); + const element = useRoutes(tabs, location); + + const currentPath = `/${useParams()['*']}`; + const [matchedRoute] = matchRoutes(tabs, currentPath) ?? []; + + const currentTabIndex = matchedRoute + ? tabs.findIndex(t => t.path === matchedRoute.route.path) + : 0; + + const navigate = useNavigate(); + const handleTabChange = useCallback( + (index: number) => { + navigate(tabs[index].id); + }, + [navigate, tabs], + ); + + useEffect(() => { + if (!element) { + navigate(tabs[0].path); + } + }, [element, navigate, tabs]); return (
    - - {tabs[tab].element} + + {element} From f0fb3fac14001119060952b00e33733bc01d8897 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 4 Nov 2023 22:29:53 +0100 Subject: [PATCH 207/275] visualizer: make tree visualizer the default Signed-off-by: Patrik Oldsberg --- .../AppVisualizerPage/AppVisualizerPage.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/visualizer/src/components/AppVisualizerPage/AppVisualizerPage.tsx b/plugins/visualizer/src/components/AppVisualizerPage/AppVisualizerPage.tsx index cc7dca24f4..1f0b038c87 100644 --- a/plugins/visualizer/src/components/AppVisualizerPage/AppVisualizerPage.tsx +++ b/plugins/visualizer/src/components/AppVisualizerPage/AppVisualizerPage.tsx @@ -36,18 +36,18 @@ export function AppVisualizerPage() { const tabs = useMemo( () => [ - { - id: 'graph', - path: 'graph', - label: 'Graph', - element: , - }, { id: 'tree', path: 'tree', label: 'Tree', element: , }, + { + id: 'graph', + path: 'graph', + label: 'Graph', + element: , + }, { id: 'text', path: 'text', From 73a5ce31f4f02d4434afc89ac40f0cbc2a6f6dc4 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 4 Nov 2023 22:31:19 +0100 Subject: [PATCH 208/275] visualizer: rename GraphVisualizer -> DetailedVisualizer Signed-off-by: Patrik Oldsberg --- .../components/AppVisualizerPage/AppVisualizerPage.tsx | 10 +++++----- .../{GraphVisualizer.tsx => DetailedVisualizer.tsx} | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) rename plugins/visualizer/src/components/AppVisualizerPage/{GraphVisualizer.tsx => DetailedVisualizer.tsx} (99%) diff --git a/plugins/visualizer/src/components/AppVisualizerPage/AppVisualizerPage.tsx b/plugins/visualizer/src/components/AppVisualizerPage/AppVisualizerPage.tsx index 1f0b038c87..b984f8ac59 100644 --- a/plugins/visualizer/src/components/AppVisualizerPage/AppVisualizerPage.tsx +++ b/plugins/visualizer/src/components/AppVisualizerPage/AppVisualizerPage.tsx @@ -19,7 +19,7 @@ import { useApi } from '@backstage/core-plugin-api'; import { appTreeApiRef } from '@backstage/frontend-plugin-api'; import Box from '@material-ui/core/Box'; import React, { useCallback, useEffect, useMemo } from 'react'; -import { GraphVisualizer } from './GraphVisualizer'; +import { DetailedVisualizer } from './DetailedVisualizer'; import { TextVisualizer } from './TextVisualizer'; import { TreeVisualizer } from './TreeVisualizer'; import { @@ -43,10 +43,10 @@ export function AppVisualizerPage() { element: , }, { - id: 'graph', - path: 'graph', - label: 'Graph', - element: , + id: 'detailed', + path: 'detailed', + label: 'Detailed', + element: , }, { id: 'text', diff --git a/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx b/plugins/visualizer/src/components/AppVisualizerPage/DetailedVisualizer.tsx similarity index 99% rename from plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx rename to plugins/visualizer/src/components/AppVisualizerPage/DetailedVisualizer.tsx index 52d090af48..f3a76ff726 100644 --- a/plugins/visualizer/src/components/AppVisualizerPage/GraphVisualizer.tsx +++ b/plugins/visualizer/src/components/AppVisualizerPage/DetailedVisualizer.tsx @@ -353,7 +353,7 @@ function Legend() { ); } -export function GraphVisualizer({ tree }: { tree: AppTree }) { +export function DetailedVisualizer({ tree }: { tree: AppTree }) { return ( From e1071afe41f1fff8a00d50094930e214df1ae6d1 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sun, 5 Nov 2023 12:41:56 -0600 Subject: [PATCH 209/275] visualizer: square extensions in tree Signed-off-by: Patrik Oldsberg --- .../src/components/AppVisualizerPage/TreeVisualizer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/visualizer/src/components/AppVisualizerPage/TreeVisualizer.tsx b/plugins/visualizer/src/components/AppVisualizerPage/TreeVisualizer.tsx index f38acf1379..8532168bc0 100644 --- a/plugins/visualizer/src/components/AppVisualizerPage/TreeVisualizer.tsx +++ b/plugins/visualizer/src/components/AppVisualizerPage/TreeVisualizer.tsx @@ -133,7 +133,7 @@ export function Node(props: { node: NodeType }) { className={classes.node} width={paddedWidth} height={paddedHeight} - rx={10} + rx={node.type === 'node' ? 0 : 20} /> Date: Wed, 13 Dec 2023 19:47:16 +0100 Subject: [PATCH 210/275] visualizer: update naming patterns Signed-off-by: Patrik Oldsberg --- plugins/visualizer/src/plugin.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/plugins/visualizer/src/plugin.tsx b/plugins/visualizer/src/plugin.tsx index 216c1f8ee2..bb541bf4af 100644 --- a/plugins/visualizer/src/plugin.tsx +++ b/plugins/visualizer/src/plugin.tsx @@ -26,15 +26,13 @@ import React from 'react'; const rootRouteRef = createRouteRef(); const visualizerPage = createPageExtension({ - id: 'plugin.visualizer.page', defaultPath: '/visualizer', routeRef: rootRouteRef, loader: () => import('./components/AppVisualizerPage').then(m => ), }); -export const visualizerPageSidebarItem = createNavItemExtension({ - id: 'plugin.visualizer.nav.index', +export const visualizerNavItem = createNavItemExtension({ title: 'Visualizer', icon: VisualizerIcon, routeRef: rootRouteRef, @@ -42,5 +40,5 @@ export const visualizerPageSidebarItem = createNavItemExtension({ export const visualizerPlugin = createPlugin({ id: 'visualizer', - extensions: [visualizerPage, visualizerPageSidebarItem], + extensions: [visualizerPage, visualizerNavItem], }); From 3fddd065fc0ec7d3112ad459505d0df7729d5cb8 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 13 Dec 2023 20:00:30 +0100 Subject: [PATCH 211/275] visualizer: fixes for backstage/backstage Signed-off-by: Patrik Oldsberg --- .../AppVisualizerPage/DetailedVisualizer.tsx | 25 +++++++++++++------ .../AppVisualizerPage/TreeVisualizer.tsx | 1 + plugins/visualizer/src/plugin.tsx | 1 + 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/plugins/visualizer/src/components/AppVisualizerPage/DetailedVisualizer.tsx b/plugins/visualizer/src/components/AppVisualizerPage/DetailedVisualizer.tsx index f3a76ff726..2356f38cfa 100644 --- a/plugins/visualizer/src/components/AppVisualizerPage/DetailedVisualizer.tsx +++ b/plugins/visualizer/src/components/AppVisualizerPage/DetailedVisualizer.tsx @@ -20,6 +20,9 @@ import { ExtensionDataRef, RouteRef, coreExtensionData, + createApiExtension, + createNavItemExtension, + createThemeExtension, useRouteRef, } from '@backstage/frontend-plugin-api'; import Box from '@material-ui/core/Box'; @@ -63,10 +66,11 @@ const getOutputColor = createOutputColorGenerator( [coreExtensionData.reactElement.id]: colors.green[500], [coreExtensionData.routePath.id]: colors.yellow[500], [coreExtensionData.routeRef.id]: colors.purple[500], - [coreExtensionData.apiFactory.id]: colors.blue[500], - [coreExtensionData.theme.id]: colors.lime[500], - [coreExtensionData.navTarget.id]: colors.orange[500], + [createApiExtension.factoryDataRef.id]: colors.blue[500], + [createThemeExtension.themeDataRef.id]: colors.lime[500], + [createNavItemExtension.targetDataRef.id]: colors.orange[500], }, + [ colors.blue[200], colors.orange[200], @@ -187,6 +191,7 @@ function OutputLink(props: { let link: string | undefined = undefined; try { + // eslint-disable-next-line react-hooks/rules-of-hooks link = useRouteRef(routeRef as RouteRef)(); } catch { /* ignore */ @@ -257,8 +262,12 @@ function Attachments(props: { - {children.map(node => ( - + {children.map(childNode => ( + ))} @@ -320,11 +329,11 @@ function Extension(props: { node: AppNode; depth: number }) { const legendMap = { 'React Element': coreExtensionData.reactElement, - 'Utility API': coreExtensionData.apiFactory, + 'Utility API': createApiExtension.factoryDataRef, 'Route Path': coreExtensionData.routePath, 'Route Ref': coreExtensionData.routeRef, - 'Nav Target': coreExtensionData.navTarget, - Theme: coreExtensionData.theme, + 'Nav Target': createNavItemExtension.targetDataRef, + Theme: createThemeExtension.themeDataRef, }; function Legend() { diff --git a/plugins/visualizer/src/components/AppVisualizerPage/TreeVisualizer.tsx b/plugins/visualizer/src/components/AppVisualizerPage/TreeVisualizer.tsx index 8532168bc0..eac7c4e203 100644 --- a/plugins/visualizer/src/components/AppVisualizerPage/TreeVisualizer.tsx +++ b/plugins/visualizer/src/components/AppVisualizerPage/TreeVisualizer.tsx @@ -14,6 +14,7 @@ * limitations under the License. */ +import React from 'react'; import { DependencyGraph, DependencyGraphTypes, diff --git a/plugins/visualizer/src/plugin.tsx b/plugins/visualizer/src/plugin.tsx index bb541bf4af..0aa8053604 100644 --- a/plugins/visualizer/src/plugin.tsx +++ b/plugins/visualizer/src/plugin.tsx @@ -38,6 +38,7 @@ export const visualizerNavItem = createNavItemExtension({ routeRef: rootRouteRef, }); +/** @public */ export const visualizerPlugin = createPlugin({ id: 'visualizer', extensions: [visualizerPage, visualizerNavItem], From bdd5d99e4c2cb1e042fa1b28d164a3f01d1bd1a0 Mon Sep 17 00:00:00 2001 From: Ben Lambert Date: Wed, 13 Dec 2023 13:29:50 +0100 Subject: [PATCH 212/275] Apply suggestions from code review Co-authored-by: Patrik Oldsberg Signed-off-by: Ben Lambert Signed-off-by: blam --- docs/plugins/internationalization.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/plugins/internationalization.md b/docs/plugins/internationalization.md index 040e75874f..98f6a05a58 100644 --- a/docs/plugins/internationalization.md +++ b/docs/plugins/internationalization.md @@ -52,7 +52,7 @@ The API for `i18n` messages and keys can be pretty tricky to get right, as it's #### Key names -Dot notation is used when consuming these keys, and should represent a semantic hierarchy in your translations. This allows for better organization and understanding of the structure. For example: +When defining messages it is recommended to use a nested structure that represents the semantic hierarchy in your translations. This allows for better organization and understanding of the structure. For example: ```ts export const myPluginTranslationRef = createTranslationRef({ @@ -81,11 +81,11 @@ export const myPluginTranslationRef = createTranslationRef({ Think about the semantic placement of content rather than the text content itself. Group related translations under a common prefix, and use nesting to represent relationships between different parts of your application. It's good to start grouping under extensions, page sections, or visual scopes and experiences. -The translations should avoid where possible having their text content in the keys, as this can lead to ambiguity and confusion when the translation changes. +Translations should avoid using their own text content as key where possible, as this can lead to confusion if the translation changes. Instead prefer to use keys that describe the location or usage of the text. #### Key reuse -Discourage key reuse to prevent ambiguity and maintain a clear separation of concerns. Consider creating duplicate keys that are grouped under a semantic section instead. +Reusing the same key in multiple places is discouraged. This helps prevent ambiguity, and instead keeps the usage of each key as clear as possible. Consider creating duplicate keys that are grouped under a semantic section instead. #### Flat keys @@ -111,7 +111,7 @@ export const myPluginTranslationRef = createTranslationRef({ #### Plurals -There's build in support for pluralization in our `i18n` library which closely follows the `react-i18next` API. You can read more about it [here](https://www.i18next.com/translation-function/plurals). +The `i18next` library, which is used as the underlying implementation, has built-in support for pluralization. You can use this feature as is described in [the documentation](https://www.i18next.com/translation-function/plurals). We encourage you to use this feature and avoid creating different key prefixes for pluralized content. For example: From 627dabd6d36501e13c85e806eabc70d9c03e9c82 Mon Sep 17 00:00:00 2001 From: blam Date: Thu, 14 Dec 2023 15:46:49 +0100 Subject: [PATCH 213/275] chore: some more smaller tweaks Signed-off-by: blam --- docs/plugins/internationalization.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/plugins/internationalization.md b/docs/plugins/internationalization.md index 98f6a05a58..fd12452cff 100644 --- a/docs/plugins/internationalization.md +++ b/docs/plugins/internationalization.md @@ -6,7 +6,7 @@ description: Documentation on adding internationalization to the plugin ## Overview -The Backstage core function provides internationalization for plugins +The Backstage core function provides internationalization for plugins. The underlying library is [`i18next`](https://www.i18next.com/) with some additional Backstage typescript magic for type safety with keys. ## For a plugin developer @@ -46,6 +46,8 @@ return ( ); ``` +You will see how the initial dictionary structure and nesting gets converted into dot notation, so we encourage `camelCase` in key names and lean on the nesting structure to separate keys. + ### Guidelines for `i18n` messages and keys The API for `i18n` messages and keys can be pretty tricky to get right, as it's a pretty flexible API. We've put together some guidelines to help you get started that encourage good practices when thinking about translating plugins: @@ -83,6 +85,16 @@ Think about the semantic placement of content rather than the text content itsel Translations should avoid using their own text content as key where possible, as this can lead to confusion if the translation changes. Instead prefer to use keys that describe the location or usage of the text. +#### Common Key names + +This list is intended to grow over time, but below are some examples of common key names and patterns that we encourage you to use where possible: + +- `${page}.title` +- `${page}.subtitle` +- `${page}.description` + +- `${page}.header.title` + #### Key reuse Reusing the same key in multiple places is discouraged. This helps prevent ambiguity, and instead keeps the usage of each key as clear as possible. Consider creating duplicate keys that are grouped under a semantic section instead. From 51754bca1971cf8d5a3d68baaa1b2d5fda618389 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Thu, 14 Dec 2023 15:59:25 +0100 Subject: [PATCH 214/275] make the loader into a proper interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- packages/frontend-app-api/api-report.md | 9 ++-- .../src/wiring/createApp.test.tsx | 54 ++++++++++++------- .../frontend-app-api/src/wiring/createApp.tsx | 28 ++++++---- 3 files changed, 59 insertions(+), 32 deletions(-) diff --git a/packages/frontend-app-api/api-report.md b/packages/frontend-app-api/api-report.md index 08db759511..e7dd584734 100644 --- a/packages/frontend-app-api/api-report.md +++ b/packages/frontend-app-api/api-report.md @@ -24,9 +24,12 @@ export function createApp(options?: { }; // @public -export type CreateAppFeatureLoader = (options: { - config: ConfigApi; -}) => Promise; +export interface CreateAppFeatureLoader { + getLoaderName(): string; + load(options: { config: ConfigApi }): Promise<{ + features: FrontendFeature[]; + }>; +} // @public export type CreateAppRouteBinder = < diff --git a/packages/frontend-app-api/src/wiring/createApp.test.tsx b/packages/frontend-app-api/src/wiring/createApp.test.tsx index 244ce625fb..dc39ab3ae5 100644 --- a/packages/frontend-app-api/src/wiring/createApp.test.tsx +++ b/packages/frontend-app-api/src/wiring/createApp.test.tsx @@ -25,7 +25,7 @@ import { createThemeExtension, } from '@backstage/frontend-plugin-api'; import { screen, waitFor } from '@testing-library/react'; -import { createApp } from './createApp'; +import { CreateAppFeatureLoader, createApp } from './createApp'; import { MockConfigApi, renderWithEffects } from '@backstage/test-utils'; import React from 'react'; import { featureFlagsApiRef, useApi } from '@backstage/core-plugin-api'; @@ -100,23 +100,32 @@ describe('createApp', () => { }); it('should support feature loaders', async () => { + const loader: CreateAppFeatureLoader = { + getLoaderName() { + return 'test-loader'; + }, + async load({ config }) { + return { + features: [ + createPlugin({ + id: 'test', + extensions: [ + createPageExtension({ + defaultPath: '/', + loader: async () =>
    {config.getString('key')}
    , + }), + ], + }), + ], + }; + }, + }; + const app = createApp({ configLoader: async () => ({ config: new MockConfigApi({ key: 'config-value' }), }), - features: [ - async ({ config }) => [ - createPlugin({ - id: 'test', - extensions: [ - createPageExtension({ - defaultPath: '/', - loader: async () =>
    {config.getString('key')}
    , - }), - ], - }), - ], - ], + features: [loader], }); await renderWithEffects(app.createRoot()); @@ -127,21 +136,26 @@ describe('createApp', () => { }); it('should propagate errors thrown by feature loaders', async () => { + const loader: CreateAppFeatureLoader = { + getLoaderName() { + return 'test-loader'; + }, + async load() { + throw new TypeError('boom'); + }, + }; + const app = createApp({ configLoader: async () => ({ config: new MockConfigApi({}), }), - features: [ - async () => { - throw new TypeError('boom'); - }, - ], + features: [loader], }); await expect( renderWithEffects(app.createRoot()), ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Failed to read frontend features from loader, TypeError: boom"`, + `"Failed to read frontend features from loader 'test-loader', TypeError: boom"`, ); }); diff --git a/packages/frontend-app-api/src/wiring/createApp.tsx b/packages/frontend-app-api/src/wiring/createApp.tsx index f3b32db399..572e88e647 100644 --- a/packages/frontend-app-api/src/wiring/createApp.tsx +++ b/packages/frontend-app-api/src/wiring/createApp.tsx @@ -244,9 +244,19 @@ function deduplicateFeatures( * * @public */ -export type CreateAppFeatureLoader = (options: { - config: ConfigApi; -}) => Promise; +export interface CreateAppFeatureLoader { + /** + * Returns name of this loader. suitable for showing to users. + */ + getLoaderName(): string; + + /** + * Loads a number of features dynamically. + */ + load(options: { config: ConfigApi }): Promise<{ + features: FrontendFeature[]; + }>; +} /** @public */ export function createApp(options?: { @@ -266,20 +276,20 @@ export function createApp(options?: { const discoveredFeatures = getAvailableFeatures(config); const providedFeatures: FrontendFeature[] = []; - for (const feature of options?.features ?? []) { - if (typeof feature === 'function') { + for (const entry of options?.features ?? []) { + if ('load' in entry) { try { - const loadedFeatures = await feature({ config }); - providedFeatures.push(...loadedFeatures); + const result = await entry.load({ config }); + providedFeatures.push(...result.features); } catch (e) { throw new Error( - `Failed to read frontend features from loader, ${stringifyError( + `Failed to read frontend features from loader '${entry.getLoaderName()}', ${stringifyError( e, )}`, ); } } else { - providedFeatures.push(feature); + providedFeatures.push(entry); } } From b38d7437ebe2d2311a17946e1f071e4a6c91c76d Mon Sep 17 00:00:00 2001 From: Youngjun Date: Fri, 15 Dec 2023 10:13:04 +0900 Subject: [PATCH 215/275] Add README trnaslated into Korean Korean was added to README. Words that can be used as nouns were kept the same. Signed-off-by: Youngjun --- README-ko_kr.md | 75 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 README-ko_kr.md diff --git a/README-ko_kr.md b/README-ko_kr.md new file mode 100644 index 0000000000..3f4993658d --- /dev/null +++ b/README-ko_kr.md @@ -0,0 +1,75 @@ +[![headline](docs/assets/headline.png)](https://backstage.io/) + +# [Backstage](https://backstage.io) + +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) +[![CNCF Status](https://img.shields.io/badge/cncf%20status-incubation-blue.svg)](https://www.cncf.io/projects) +[![Discord](https://img.shields.io/discord/687207715902193673?logo=discord&label=Discord&color=5865F2&logoColor=white)](https://discord.gg/backstage-687207715902193673) +![Code style](https://img.shields.io/badge/code_style-prettier-ff69b4.svg) +[![Codecov](https://img.shields.io/codecov/c/github/backstage/backstage)](https://codecov.io/gh/backstage/backstage) +[![](https://img.shields.io/github/v/release/backstage/backstage)](https://github.com/backstage/backstage/releases) +[![Uffizzi](https://img.shields.io/endpoint?url=https%3A%2F%2Fapp.uffizzi.com%2Fapi%2Fv1%2Fpublic%2Fshields%2Fgithub.com%2Fbackstage%2Fbackstage)](https://app.uffizzi.com/ephemeral-environments/backstage/backstage) +[![OpenSSF Best Practices](https://bestpractices.coreinfrastructure.org/projects/7678/badge)](https://bestpractices.coreinfrastructure.org/projects/7678) +[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/backstage/backstage/badge)](https://securityscorecards.dev/viewer/?uri=github.com/backstage/backstage) + +## What is Backstage? + +[Backstage](https://backstage.io/) is an open platform for building developer portals. Powered by a centralized software catalog, Backstage restores order to your microservices and infrastructure and enables your product teams to ship high-quality code quickly without compromising autonomy. + +Backstage unifies all your infrastructure tooling, services, and documentation to create a streamlined development environment from end to end. + +![software-catalog](docs/assets/header.png) + +Out of the box, Backstage includes: + +- [Backstage Software Catalog](https://backstage.io/docs/features/software-catalog/) for managing all your software such as microservices, libraries, data pipelines, websites, and ML models +- [Backstage Software Templates](https://backstage.io/docs/features/software-templates/) for quickly spinning up new projects and standardizing your tooling with your organization’s best practices +- [Backstage TechDocs](https://backstage.io/docs/features/techdocs/) for making it easy to create, maintain, find, and use technical documentation, using a "docs like code" approach +- Plus, a growing ecosystem of [open source plugins](https://github.com/backstage/backstage/tree/master/plugins) that further expand Backstage’s customizability and functionality + +Backstage was created by Spotify but is now hosted by the [Cloud Native Computing Foundation (CNCF)](https://www.cncf.io) as an Incubation level project. For more information, see the [announcement](https://backstage.io/blog/2022/03/16/backstage-turns-two#out-of-the-sandbox-and-into-incubation). + +## Project roadmap + +For information about the detailed project roadmap including delivered milestones, see [the Roadmap](https://backstage.io/docs/overview/roadmap). + +## Getting Started + +To start using Backstage, see the [Getting Started documentation](https://backstage.io/docs/getting-started). + +## Documentation + +The documentation of Backstage includes: + +- [Main documentation](https://backstage.io/docs) +- [Software Catalog](https://backstage.io/docs/features/software-catalog/) +- [Architecture](https://backstage.io/docs/overview/architecture-overview) ([Decisions](https://backstage.io/docs/architecture-decisions/)) +- [Designing for Backstage](https://backstage.io/docs/dls/design) +- [Storybook - UI components](https://backstage.io/storybook) + +## Community + +To engage with our community, you can use the following resources: + +- [Discord chatroom](https://discord.gg/backstage-687207715902193673) - Get support or discuss the project +- [Contributing to Backstage](https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md) - Start here if you want to contribute +- [RFCs](https://github.com/backstage/backstage/labels/rfc) - Help shape the technical direction +- [FAQ](https://backstage.io/docs/FAQ) - Frequently Asked Questions +- [Code of Conduct](CODE_OF_CONDUCT.md) - This is how we roll +- [Adopters](ADOPTERS.md) - Companies already using Backstage +- [Blog](https://backstage.io/blog/) - Announcements and updates +- [Newsletter](https://spoti.fi/backstagenewsletter) - Subscribe to our email newsletter +- [Backstage Community Sessions](https://github.com/backstage/community) - Join monthly meetups and explore Backstage community +- Give us a star ⭐️ - If you are using Backstage or think it is an interesting project, we would love a star ❤️ + +## License + +Copyright 2020-2023 © The Backstage Authors. All rights reserved. The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation, please see our Trademark Usage page: https://www.linuxfoundation.org/trademark-usage + +Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + +## Security + +Please report sensitive security issues using Spotify's [bug-bounty program](https://hackerone.com/spotify) rather than GitHub. + +For further details, see our complete [security release process](SECURITY.md). From a07b3b373c7dfef28d4c8a62bcf7739aa3a2a43c Mon Sep 17 00:00:00 2001 From: Youngjun Date: Fri, 15 Dec 2023 10:23:32 +0900 Subject: [PATCH 216/275] ADD README translated into Korean move link Signed-off-by: Youngjun --- README-ko_kr.md | 62 +++++++++++++++++++++++++------------------------ README.md | 1 + 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/README-ko_kr.md b/README-ko_kr.md index 3f4993658d..42049f434b 100644 --- a/README-ko_kr.md +++ b/README-ko_kr.md @@ -1,6 +1,8 @@ [![headline](docs/assets/headline.png)](https://backstage.io/) + # [Backstage](https://backstage.io) +[English](README.md) \| 한국어 [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![CNCF Status](https://img.shields.io/badge/cncf%20status-incubation-blue.svg)](https://www.cncf.io/projects) @@ -12,34 +14,33 @@ [![OpenSSF Best Practices](https://bestpractices.coreinfrastructure.org/projects/7678/badge)](https://bestpractices.coreinfrastructure.org/projects/7678) [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/backstage/backstage/badge)](https://securityscorecards.dev/viewer/?uri=github.com/backstage/backstage) -## What is Backstage? +## 백스테이지(Backstage)란? -[Backstage](https://backstage.io/) is an open platform for building developer portals. Powered by a centralized software catalog, Backstage restores order to your microservices and infrastructure and enables your product teams to ship high-quality code quickly without compromising autonomy. +[백스테이지(Backstage)](https://backstage.io/) 는 개발자 포털 구출을 위한 개방형 플랫폼입니다. 중앙 집중식 소프트웨어 카탈로그를 기반으로하는 Backstage는 마이크로 서비스와 인프라의 질서를 복원하고 제품팀이 자율성을 훼손하지 않고 고품질 코드를 신속하게 출시할 수 있도록 지원합니다. -Backstage unifies all your infrastructure tooling, services, and documentation to create a streamlined development environment from end to end. +Backstage 는 모든 인프라 도구, 서비스 및 문서를 통합하여 처음부터 끝까지 간소화된 개발 환경을 만듭니다. ![software-catalog](docs/assets/header.png) -Out of the box, Backstage includes: +Backstage 다음을 포함합니다: +- [Backstage Software Catalog](https://backstage.io/docs/features/software-catalog/) 마이크로 서비스, 라이브러리, 데이터 파이프라인, 웹 사이트, ML 모델 등 모든 소프트웨어 관리 +- [Backstage Software Templates](https://backstage.io/docs/features/software-templates/) 새로운 프로젝트를 신속하게 시작하고 조직의 모밤 사례에따라 도구를 표준화 +- [Backstage TechDocs](https://backstage.io/docs/features/techdocs/) "docs like code" 접근 방식을 사용하여 기술 문서를 쉽게 작성, 유지 관리, 검색 및 사용 +- [open source plugins](https://github.com/backstage/backstage/tree/master/plugins) Backstage의 사용자 정의 가능성과 기능을 확장 -- [Backstage Software Catalog](https://backstage.io/docs/features/software-catalog/) for managing all your software such as microservices, libraries, data pipelines, websites, and ML models -- [Backstage Software Templates](https://backstage.io/docs/features/software-templates/) for quickly spinning up new projects and standardizing your tooling with your organization’s best practices -- [Backstage TechDocs](https://backstage.io/docs/features/techdocs/) for making it easy to create, maintain, find, and use technical documentation, using a "docs like code" approach -- Plus, a growing ecosystem of [open source plugins](https://github.com/backstage/backstage/tree/master/plugins) that further expand Backstage’s customizability and functionality +Backstage는 Spotify에서 제작되었지만 현재는 [Cloud Native Computing Foundation(CNCF)](https://www.cncf.io)에서 인큐베이션 수준 프로젝트로 호스팅되고 있습니다. 추가적인 정보는 [announcement](https://backstage.io/blog/2022/03/16/backstage-turns-two#out-of-the-sandbox-and-into-incubation)를 참조하세요. -Backstage was created by Spotify but is now hosted by the [Cloud Native Computing Foundation (CNCF)](https://www.cncf.io) as an Incubation level project. For more information, see the [announcement](https://backstage.io/blog/2022/03/16/backstage-turns-two#out-of-the-sandbox-and-into-incubation). +## 프로젝트 로드맵 -## Project roadmap +제공된 마일스톤을 포함한 자세한 프로젝트 로드맵에 대한 자세한 내용은 [the Roadmap](https://backstage.io/docs/overview/roadmap)을 참조하세요. -For information about the detailed project roadmap including delivered milestones, see [the Roadmap](https://backstage.io/docs/overview/roadmap). +## 시작하기 -## Getting Started +Backstage를 시작하기위해 [Getting Started documentation](https://backstage.io/docs/getting-started)를 참조하세요. -To start using Backstage, see the [Getting Started documentation](https://backstage.io/docs/getting-started). +## 문서 -## Documentation - -The documentation of Backstage includes: +Backstage의 문서는 다음을 포함합니다: - [Main documentation](https://backstage.io/docs) - [Software Catalog](https://backstage.io/docs/features/software-catalog/) @@ -47,20 +48,20 @@ The documentation of Backstage includes: - [Designing for Backstage](https://backstage.io/docs/dls/design) - [Storybook - UI components](https://backstage.io/storybook) -## Community +## 커뮤니티 -To engage with our community, you can use the following resources: +커뮤니티에 참여하려면 다음 리소스를 사용하세요: -- [Discord chatroom](https://discord.gg/backstage-687207715902193673) - Get support or discuss the project -- [Contributing to Backstage](https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md) - Start here if you want to contribute -- [RFCs](https://github.com/backstage/backstage/labels/rfc) - Help shape the technical direction -- [FAQ](https://backstage.io/docs/FAQ) - Frequently Asked Questions -- [Code of Conduct](CODE_OF_CONDUCT.md) - This is how we roll -- [Adopters](ADOPTERS.md) - Companies already using Backstage -- [Blog](https://backstage.io/blog/) - Announcements and updates -- [Newsletter](https://spoti.fi/backstagenewsletter) - Subscribe to our email newsletter -- [Backstage Community Sessions](https://github.com/backstage/community) - Join monthly meetups and explore Backstage community -- Give us a star ⭐️ - If you are using Backstage or think it is an interesting project, we would love a star ❤️ +- [Discord chatroom](https://discord.gg/backstage-687207715902193673) - 지원 및 프로젝트 토론 +- [Contributing to Backstage](https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md) - 프로젝트 기여 +- [RFCs](https://github.com/backstage/backstage/labels/rfc) - 기술 방향을 정하는 데 도움을 주세요. +- [FAQ](https://backstage.io/docs/FAQ) - 자주 묻는 질문들 +- [Code of Conduct](CODE_OF_CONDUCT.md) - 커뮤니티 운영 방식 +- [Adopters](ADOPTERS.md) - Backstage를 사용하고 있는 기업 +- [Blog](https://backstage.io/blog/) - 공지사항 및 업데이트 +- [Newsletter](https://spoti.fi/backstagenewsletter) - 이메일 뉴스레터 구독 +- [Backstage Community Sessions](https://github.com/backstage/community) - 월간 모임 참여 및 커뮤니티 톺아보기 +- Backstage를 사용중이거나 흥미로운 프로젝트라고 생각하신다면 별표를 눌러주세요. 별표는 사랑입니다 ❤️ ## License @@ -68,8 +69,9 @@ Copyright 2020-2023 © The Backstage Authors. All rights reserved. The Linux Fou Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 -## Security +## 보안 +민감한 보안문제는 Github가 아닌 Spotify의 [bug-bounty program](https://hackerone.com/spotify) 통해 신고해주세요 Please report sensitive security issues using Spotify's [bug-bounty program](https://hackerone.com/spotify) rather than GitHub. -For further details, see our complete [security release process](SECURITY.md). +자세한 내용은 [security release process](SECURITY.md)를 참고하세요. diff --git a/README.md b/README.md index 3f4993658d..9f34c83dc1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ [![headline](docs/assets/headline.png)](https://backstage.io/) # [Backstage](https://backstage.io) +English \| [한국어](README-ko_kr.md) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![CNCF Status](https://img.shields.io/badge/cncf%20status-incubation-blue.svg)](https://www.cncf.io/projects) From d86cd98301d0afe24df1bbe2e43bad7685e88f5f Mon Sep 17 00:00:00 2001 From: Niklas Aronsson Date: Wed, 13 Dec 2023 12:09:42 +0100 Subject: [PATCH 217/275] Scaffolder-backend-gerrit: Add dry run support for 'publish:gerrit' Signed-off-by: Niklas Aronsson --- .changeset/early-pumpkins-hope.md | 5 +++ .../src/actions/gerrit.test.ts | 15 ++++++++ .../src/actions/gerrit.ts | 36 ++++++++++++++----- 3 files changed, 48 insertions(+), 8 deletions(-) create mode 100644 .changeset/early-pumpkins-hope.md diff --git a/.changeset/early-pumpkins-hope.md b/.changeset/early-pumpkins-hope.md new file mode 100644 index 0000000000..ab73cafc0e --- /dev/null +++ b/.changeset/early-pumpkins-hope.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-gerrit': patch +--- + +Add dry run support for the `publish:gerrit` action. diff --git a/plugins/scaffolder-backend-module-gerrit/src/actions/gerrit.test.ts b/plugins/scaffolder-backend-module-gerrit/src/actions/gerrit.test.ts index b56c27f59e..d05c8727c4 100644 --- a/plugins/scaffolder-backend-module-gerrit/src/actions/gerrit.test.ts +++ b/plugins/scaffolder-backend-module-gerrit/src/actions/gerrit.test.ts @@ -241,7 +241,22 @@ describe('publish:gerrit', () => { 'https://gerrithost.org/repo/+/refs/heads/master', ); }); + it('should not create new projects on dryRun', async () => { + await action.handler({ + ...mockContext, + isDryRun: true, + input: { + ...mockContext.input, + repoUrl: 'gerrithost.org?workspace=workspace&repo=repo', + sourcePath: 'repository/', + }, + }); + expect(mockContext.output).toHaveBeenCalledWith( + 'commitHash', + 'abcd-dry-run-1234', + ); + }); afterEach(() => { jest.resetAllMocks(); }); diff --git a/plugins/scaffolder-backend-module-gerrit/src/actions/gerrit.ts b/plugins/scaffolder-backend-module-gerrit/src/actions/gerrit.ts index b7369fd5d8..6f729227e6 100644 --- a/plugins/scaffolder-backend-module-gerrit/src/actions/gerrit.ts +++ b/plugins/scaffolder-backend-module-gerrit/src/actions/gerrit.ts @@ -100,6 +100,7 @@ export function createPublishGerritAction(options: { sourcePath?: string; }>({ id: 'publish:gerrit', + supportsDryRun: true, description: 'Initializes a git repository of the content in the workspace, and publishes it to Gerrit.', examples, @@ -190,6 +191,31 @@ export function createPublishGerritAction(options: { ); } + const repoContentsUrl = `${integrationConfig.config.gitilesBaseUrl}/${repo}/+/refs/heads/${defaultBranch}`; + const remoteUrl = `${integrationConfig.config.cloneUrl}/a/${repo}`; + const gitName = gitAuthorName + ? gitAuthorName + : config.getOptionalString('scaffolder.defaultAuthor.name'); + const gitEmail = gitAuthorEmail + ? gitAuthorEmail + : config.getOptionalString('scaffolder.defaultAuthor.email'); + const commitMessage = generateCommitMessage(config, gitCommitMessage); + + if (ctx.isDryRun) { + ctx.logger.info( + `Dry run arguments: ${{ + gitName, + gitEmail, + commitMessage, + ...ctx.input, + }}`, + ); + ctx.output('remoteUrl', remoteUrl); + ctx.output('commitHash', 'abcd-dry-run-1234'); + ctx.output('repoContentsUrl', repoContentsUrl); + return; + } + await createGerritProject(integrationConfig.config, { description, owner: owner, @@ -201,15 +227,10 @@ export function createPublishGerritAction(options: { password: integrationConfig.config.password!, }; const gitAuthorInfo = { - name: gitAuthorName - ? gitAuthorName - : config.getOptionalString('scaffolder.defaultAuthor.name'), - email: gitAuthorEmail - ? gitAuthorEmail - : config.getOptionalString('scaffolder.defaultAuthor.email'), + name: gitName, + email: gitEmail, }; - const remoteUrl = `${integrationConfig.config.cloneUrl}/a/${repo}`; const commitResult = await initRepoAndPush({ dir: getRepoSourceDirectory(ctx.workspacePath, sourcePath), remoteUrl, @@ -220,7 +241,6 @@ export function createPublishGerritAction(options: { gitAuthorInfo, }); - const repoContentsUrl = `${integrationConfig.config.gitilesBaseUrl}/${repo}/+/refs/heads/${defaultBranch}`; ctx.output('remoteUrl', remoteUrl); ctx.output('commitHash', commitResult?.commitHash); ctx.output('repoContentsUrl', repoContentsUrl); From b548f02fbf6995140a10551fc6b7b4b3151c92f8 Mon Sep 17 00:00:00 2001 From: blam Date: Fri, 15 Dec 2023 09:42:32 +0100 Subject: [PATCH 218/275] chore: fix a bug that properties is set to empty object when it should not be present when parsing template schema Signed-off-by: blam --- .../src/next/hooks/useTemplateSchema.test.tsx | 1 - .../src/next/hooks/useTemplateSchema.ts | 27 ++++++++++++------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/plugins/scaffolder-react/src/next/hooks/useTemplateSchema.test.tsx b/plugins/scaffolder-react/src/next/hooks/useTemplateSchema.test.tsx index d2771b2eb9..ac55d73a04 100644 --- a/plugins/scaffolder-react/src/next/hooks/useTemplateSchema.test.tsx +++ b/plugins/scaffolder-react/src/next/hooks/useTemplateSchema.test.tsx @@ -263,7 +263,6 @@ describe('useTemplateSchema', () => { expect(first.schema).toEqual({ type: 'object', - properties: {}, }); }); }); diff --git a/plugins/scaffolder-react/src/next/hooks/useTemplateSchema.ts b/plugins/scaffolder-react/src/next/hooks/useTemplateSchema.ts index 838f8b1c30..aa5cefbaec 100644 --- a/plugins/scaffolder-react/src/next/hooks/useTemplateSchema.ts +++ b/plugins/scaffolder-react/src/next/hooks/useTemplateSchema.ts @@ -59,13 +59,18 @@ export const useTemplateSchema = ( return stepFeatureFlag ? featureFlags.isActive(stepFeatureFlag) : true; }) // Then filter out the properties that are not enabled with feature flag - .map(step => ({ - ...step, - schema: { - ...step.schema, - // Title is rendered at the top of the page, so let's ignore this from jsonschemaform - title: undefined, - properties: Object.fromEntries( + .map(step => { + const strippedSchema = { + ...step, + schema: { + ...step.schema, + // Title is rendered at the top of the page, so let's ignore this from jsonschemaform + title: undefined, + }, + } as ParsedTemplateSchema; + + if (step.schema?.properties) { + strippedSchema.schema.properties = Object.fromEntries( Object.entries((step.schema?.properties ?? []) as JsonObject).filter( ([key]) => { const stepFeatureFlag = @@ -75,9 +80,11 @@ export const useTemplateSchema = ( : true; }, ), - ), - }, - })); + ); + } + + return strippedSchema; + }); return { presentation: manifest.presentation, From 670c7ccde56d7730d502b6e1ad55b1fda6c6081b Mon Sep 17 00:00:00 2001 From: blam Date: Fri, 15 Dec 2023 09:43:54 +0100 Subject: [PATCH 219/275] chore: add changeset Signed-off-by: blam --- .changeset/empty-poets-camp.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/empty-poets-camp.md diff --git a/.changeset/empty-poets-camp.md b/.changeset/empty-poets-camp.md new file mode 100644 index 0000000000..3e5e410ea1 --- /dev/null +++ b/.changeset/empty-poets-camp.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-react': patch +--- + +Fix bug where `properties` is set to empty object when it should be empty for schema dependencies From cb6a65e3809a38366880a2e63e749009871ee002 Mon Sep 17 00:00:00 2001 From: npiyush97 Date: Fri, 15 Dec 2023 16:47:03 +0530 Subject: [PATCH 220/275] Fixed Bug related defaultCommitMessage Signed-off-by: npiyush97 --- .changeset/clever-monkeys-double.md | 5 ++ .../src/actions/github.ts | 2 +- .../src/actions/helper.test.ts | 47 +++++++++++++++++++ .../src/actions/helpers.ts | 5 +- 4 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 .changeset/clever-monkeys-double.md create mode 100644 plugins/scaffolder-backend-module-github/src/actions/helper.test.ts diff --git a/.changeset/clever-monkeys-double.md b/.changeset/clever-monkeys-double.md new file mode 100644 index 0000000000..9fbf541201 --- /dev/null +++ b/.changeset/clever-monkeys-double.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-github': patch +--- + +The `scaffolder.defaultCommitMessage` config value is now being used if provided and uses "initial commit" when it is not provided. diff --git a/plugins/scaffolder-backend-module-github/src/actions/github.ts b/plugins/scaffolder-backend-module-github/src/actions/github.ts index 62f657b01c..91d7a34aea 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/github.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/github.ts @@ -187,7 +187,7 @@ export function createPublishGithubAction(options: { protectDefaultBranch = true, protectEnforceAdmins = true, deleteBranchOnMerge = false, - gitCommitMessage = 'initial commit', + gitCommitMessage, gitAuthorName, gitAuthorEmail, allowMergeCommit = true, diff --git a/plugins/scaffolder-backend-module-github/src/actions/helper.test.ts b/plugins/scaffolder-backend-module-github/src/actions/helper.test.ts new file mode 100644 index 0000000000..3934e07db7 --- /dev/null +++ b/plugins/scaffolder-backend-module-github/src/actions/helper.test.ts @@ -0,0 +1,47 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ConfigReader } from '@backstage/config'; +import { getGitCommitMessage } from './helpers'; + +describe('getGitCommitMessage', () => { + it('should return gitCommitMessage when provided', () => { + const mockConfig = new ConfigReader({}); + const gitCommitMessage = 'Custom commit message'; + + const result = getGitCommitMessage(gitCommitMessage, mockConfig); + + expect(result).toEqual('Custom commit message'); + }); + + it('should return default commit message from config when gitCommitMessage is undefined', () => { + const mockConfig = new ConfigReader({ + scaffolder: { + defaultCommitMessage: 'Default commit message', + }, + }); + const result = getGitCommitMessage(undefined, mockConfig); + + expect(result).toEqual('Default commit message'); + }); + + it('should return undefined when both gitCommitMessage and default commit message are undefined', () => { + const mockConfig = new ConfigReader({}); + const result = getGitCommitMessage(undefined, mockConfig); + + expect(result).toBeUndefined(); + }); +}); diff --git a/plugins/scaffolder-backend-module-github/src/actions/helpers.ts b/plugins/scaffolder-backend-module-github/src/actions/helpers.ts index c6c4bd4ce5..4d95a6494f 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/helpers.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/helpers.ts @@ -354,9 +354,8 @@ export async function initRepoPushAndProtect( : config.getOptionalString('scaffolder.defaultAuthor.email'), }; - const commitMessage = gitCommitMessage - ? gitCommitMessage - : config.getOptionalString('scaffolder.defaultCommitMessage'); + const commitMessage = + getGitCommitMessage(gitCommitMessage, config) || 'initial commit'; const commitResult = await initRepoAndPush({ dir: getRepoSourceDirectory(workspacePath, sourcePath), From a113012e761302fcfb6ddad4343e68170bbb16b9 Mon Sep 17 00:00:00 2001 From: krolik Date: Fri, 15 Dec 2023 12:30:01 +0100 Subject: [PATCH 221/275] Adding Nobl9 plugin to the Directory Signed-off-by: krolik --- microsite/data/plugins/nobl9.yaml | 10 ++++++++++ microsite/static/img/nobl9.svg | 4 ++++ 2 files changed, 14 insertions(+) create mode 100644 microsite/data/plugins/nobl9.yaml create mode 100644 microsite/static/img/nobl9.svg diff --git a/microsite/data/plugins/nobl9.yaml b/microsite/data/plugins/nobl9.yaml new file mode 100644 index 0000000000..ee447fd626 --- /dev/null +++ b/microsite/data/plugins/nobl9.yaml @@ -0,0 +1,10 @@ +--- +title: Nobl9 +author: Nobl9 +authorUrl: https://nobl9.com +category: Reliability +description: View and drill down into the reliability of your services via Nobl9 SLOs and error budgets. +documentation: https://github.com/nobl9/nobl9-backstage-plugin/blob/main/README.MD +iconUrl: /img/nobl9.svg +npmPackageName: '@nobl9/nobl9-backstage-plugin' +addedDate: '2023-12-15' diff --git a/microsite/static/img/nobl9.svg b/microsite/static/img/nobl9.svg new file mode 100644 index 0000000000..a4065df602 --- /dev/null +++ b/microsite/static/img/nobl9.svg @@ -0,0 +1,4 @@ + + + + From 6aa0cda977d59212e1a2ad44418b878d67adc671 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Tue, 5 Dec 2023 10:58:17 +0100 Subject: [PATCH 222/275] add api docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .../architecture-utility-apis.drawio.svg | 314 ++++++++++++++++++ .../architecture/06-utility-apis.md | 39 ++- docs/frontend-system/utility-apis/01-index.md | 37 +++ .../utility-apis/02-creating.md | 92 +++++ .../utility-apis/03-consuming.md | 67 ++++ .../utility-apis/04-configuring.md | 25 ++ .../utility-apis/05-migrating.md | 9 + 7 files changed, 582 insertions(+), 1 deletion(-) create mode 100644 docs/assets/frontend-system/architecture-utility-apis.drawio.svg create mode 100644 docs/frontend-system/utility-apis/01-index.md create mode 100644 docs/frontend-system/utility-apis/02-creating.md create mode 100644 docs/frontend-system/utility-apis/03-consuming.md create mode 100644 docs/frontend-system/utility-apis/04-configuring.md create mode 100644 docs/frontend-system/utility-apis/05-migrating.md diff --git a/docs/assets/frontend-system/architecture-utility-apis.drawio.svg b/docs/assets/frontend-system/architecture-utility-apis.drawio.svg new file mode 100644 index 0000000000..a7008b1126 --- /dev/null +++ b/docs/assets/frontend-system/architecture-utility-apis.drawio.svg @@ -0,0 +1,314 @@ + + + + + + + +
    +
    +
    + App +
    +
    +
    +
    + + App + +
    +
    + + + + + +
    +
    +
    + provides +
    +
    +
    +
    + + provides + +
    +
    + + + + +
    +
    +
    + Catalog Plugin +
    + + plugin:catalog + +
    +
    +
    +
    + + Catalog Plugin... + +
    +
    + + + + + +
    +
    +
    + + replaces +
    + implementation +
    +
    +
    +
    +
    +
    + + replaces... + +
    +
    + + + + +
    +
    +
    + Extension Overrides +
    +
    +
    +
    + + Extension Overr... + +
    +
    + + + + + +
    +
    +
    + provides +
    +
    +
    +
    + + provides + +
    +
    + + + + +
    +
    +
    + Todo Plugin +
    + + plugin:todo + +
    +
    +
    +
    + + Todo Plugin... + +
    +
    + + + + +
    +
    +
    + Backstage Frontend Framework +
    +
    +
    +
    + + Backstage Frontend Framework + +
    +
    + + + + + + +
    +
    +
    + + Catalog Client Utility API +
    + + api:plugin.catalog.service + +
    +
    +
    +
    +
    + + Catalog Client Utility API... + +
    +
    + + + + +
    +
    +
    + + Todo Utility API +
    + + api:plugin.todo.api + +
    +
    +
    +
    +
    + + Todo Utility API... + +
    +
    + + + + + + + + + +
    +
    +
    + + installs + +
    +
    +
    +
    + + installs + +
    +
    + + + + +
    +
    +
    + + Fetch Utility API +
    + + api:core.fetch + +
    +
    +
    +
    +
    + + Fetch Utility API... + +
    +
    + + + + + +
    +
    +
    + provides +
    +
    +
    +
    + + provides + +
    +
    + + + + + +
    +
    +
    + depends on +
    +
    +
    +
    + + depends on + +
    +
    + + + + + +
    +
    +
    + depends on +
    +
    +
    +
    + + depends on + +
    +
    +
    + + + + + Text is not SVG - cannot display + + + +
    diff --git a/docs/frontend-system/architecture/06-utility-apis.md b/docs/frontend-system/architecture/06-utility-apis.md index 135f60744a..4fbbf1af94 100644 --- a/docs/frontend-system/architecture/06-utility-apis.md +++ b/docs/frontend-system/architecture/06-utility-apis.md @@ -8,4 +8,41 @@ description: Utility APIs > **NOTE: The new frontend system is in a highly experimental phase** -See [Utility APIs docs](../../api/utility-apis.md). +## Overview + +Utility APIs are pieces of standalone functionality, interfaces that can be +requested by plugins to use. They are defined by a TypeScript interface as well +as a reference (an "API ref") used to access its implementation. They can be +provided both by plugins and the core framework, and are themselves +[extensions](../architecture/03-extensions.md) that can have inputs, be +replaced, and be declaratively configured in your app-config. + +A common example of a utility API is a client interface to interact with the +backend part of a plugin, such as the catalog client. Any frontend plugin can +then request an implementation of that interface to make requests through. + +The following diagram shows a hypothetical application, which depends on two +plugins and also provides some extra overrides. Note that both the plugins and +the core framework exposed utility APIs, and that they depended on each other. +The app also chose to use its overrides mechanism to supply a replacement +implementation of one API, which took precedence over the default one. Thus, all +consumers of that API will be sure to get that new implementation provided to +them. + +![frontend system utility apis diagram](../../assets/frontend-system/architecture-utility-apis.drawio.svg) + +## Extension structure + +All utility APIs implement the `coreExtensionData.apiFactory` output data type, +and must attach exclusively to the `core` extension's `apis` input no matter who +provided them. These defaults are provided out of the box by the +`createApiExtension` framework function. + +Since utility APIs are extensions, they can also have inputs in advanced use +cases. This is occasionally useful for complex APIs that can themselves be +extended with additional programmatic functionality by adopters. + +## Links + +- The [Using Utility APIs section](../building-plugins/03-utility-apis.md) of the plugin docs +- The legacy docs on [utility APIs](../../api/utility-apis.md) diff --git a/docs/frontend-system/utility-apis/01-index.md b/docs/frontend-system/utility-apis/01-index.md new file mode 100644 index 0000000000..353ad3ffe4 --- /dev/null +++ b/docs/frontend-system/utility-apis/01-index.md @@ -0,0 +1,37 @@ +--- +id: index +title: Utility APIs +sidebar_label: Overview +# prettier-ignore +description: Working with Utility APIs in the New Frontend System +--- + +As described [in the architecture section](../architecture/06-utility-apis.md), utility APIs are pieces of shared functionality - interfaces that can be requested by plugins to use. They are defined by a TypeScript interface as well as a reference (an "API ref") used to access its implementation. They can be provided both by plugins and the core framework, and are themselves [extensions](../architecture/03-extensions.md) that can accept inputs, be declaratively configured in your app-config, or transparently be replaced entirely with custom implementations that fulfill the same contract. + +## Creating Utility APIs + +> For details, [see the main article](./02-creating.md). + +Backstage apps, the core Backstage framework, and plugins can all expose utility APIs for general use. + +Some are available out of the box, such as the API for reading app configuration. Some are provided by third party plugins, such as the catalog client API that both the catalog itself and your own code can leverage to talk to the catalog backend. Some, you may create yourself and make available inside your Backstage instance for use within your private ecosystem of plugins. + +[The main article](./02-creating.md) describes the process of creating and exposing utility APIs of your own, for sharing functionality or configurability across plugins and apps. + +## Consuming Utility APIs + +> For details, [see the main article](./03-consuming.md). + +Once utility APIs are created, there are a few ways that they can be accessed to be consumed. + +Some utility APIs in turn depend on other utility APIs. This powerful composability lets you leverage already-written reusable pieces. In particular, you may want to rely on Backstage's framework-provided APIs e.g. for reading app configuration and many other use cases. Sometimes you request utility APIs inside your React components, e.g. for accessing i18n strings, or emitting analytics events. + +These are described in detail in [the main article](./03-consuming.md) + +## Configuring Utility APIs + +> For details, [see the main article](./04-configuring.md). + +Most utility APIs are usable directly without any configuration. But they are proper extensions, and can therefore have their implementations entirely swapped out by your app for advanced use cases. They can also be built with the ability to configured in your app-config, or to have inputs that extend their functionality. + +These cases are all described in [the main article](./04-configuring.md). diff --git a/docs/frontend-system/utility-apis/02-creating.md b/docs/frontend-system/utility-apis/02-creating.md new file mode 100644 index 0000000000..58655a24f5 --- /dev/null +++ b/docs/frontend-system/utility-apis/02-creating.md @@ -0,0 +1,92 @@ +--- +id: creating +title: Creating Utility APIs +sidebar_label: Creating APIs +# prettier-ignore +description: Creating new utility APIs in your plugins and app +--- + +## When to make a utility API + +> TODO + +## Creating the Utility API contract + +The first step toward exposing a utility API is to define its TypeScript contract, and an API ref for consumers to find it via. This should be done in [your plugin's `-react` package](../../architecture-decisions/adr011-plugin-package-structure.md), so that it can be imported by other plugins. In this example, we have an Example plugin that wants to expose a utility API for performing some type of work. + +```tsx title="in @internal/plugin-example-react" +import { createApiRef } from '@backstage/frontend-plugin-api'; + +/** + * Performs some work. + * @oublic + */ +export interface WorkApi { + doWork(): Promise; +} + +/** + * The work interface for the Example plugin. + * @public + */ +export const workApiRef = createApiRef({ + id: 'plugin.example.work', +}); +``` + +Both of these are properly exported publicly from the package, so that consumers can reach them. + +The plugin itself now wants to provide this API and its default implementation, in the form of an API extension. Doing so means that when users install the Example plugin, an instance of the Work utility API will also be automatically available in their apps - both to the Example plugin itself, and to others. We do this in the main plugin package, not the `-react` package. + +```tsx title="in @internal/plugin-example" +import { + createApiExtension, + createApiFactory, + createPlugin, + configApiRef, + ConfigApi, +} from '@backstage/frontend-plugin-api'; +import { WorkApi, workApiRef } from '@internal/plugin-example-react'; + +class WorkImpl implements WorkApi { + constructor(options: { configApi: ConfigApi }) { + /* TODO */ + } + async doWork() { + /* TODO */ + } +} + +const workApi = createApiExtension({ + api: workApiRef, + factory: () => + createApiFactory({ + api: workApiRef, + deps: { + configApi: configApiRef, + }, + factory: ({ configApi }) => { + return new WorkImpl({ configApi }); + }, + }), +}); + +/** + * The Example plugin. + * @public + */ +export default createPlugin({ + id: 'example', + extensions: [workApi], +}); +``` + +For illustration we make a skeleton implementation class and the API extension and factory for it, in the same file. These are not exported to the public surface of the plugin package; only the plugin is, as the default export. + +The code also illustrates how the API factory declares a dependency on another utility API - the core config API in this case. An instance of that utility API is then provided to the factory function. + +The resulting extension ID of the work API will be the kind `api:` followed by the plugin ID as the namespace, in this case ending up as `api:plugin.example.work`. You can now use this ID to refer to the API in app-config and elsewhere. + +## Next steps + +See [the Consuming section](./03-consuming.md) to see how to consume this new utility API in various ways. If you wish to learn how to add configurability and inputs to it, check out [the Configuring section](./04-configuring.md). diff --git a/docs/frontend-system/utility-apis/03-consuming.md b/docs/frontend-system/utility-apis/03-consuming.md new file mode 100644 index 0000000000..7c339f1bf9 --- /dev/null +++ b/docs/frontend-system/utility-apis/03-consuming.md @@ -0,0 +1,67 @@ +--- +id: consuming +title: Consuming Utility APIs +sidebar_label: Consuming APIs +# prettier-ignore +description: Consuming utility APIs +--- + +All of the utility API extensions that were passed into your app through installed plugins, get instantiated and configured in the right order by the framework, and are then made available for consumption. You can interact with these instances in the following ways. + +## Via React hooks + +The most common consumption pattern for utility APIs is to call the `useApi` hook inside React components to get an implementation via its API ref. This applies whether it was originally provided from the core framework or from a plugin. + +```tsx +import { useApi, configApiRef } from '@backstage/frontend-plugin-api'; + +const MyComponent = () => { + const configApi = useApi(configApiRef); + const baseUrl = configApi.getString('backend.baseUrl'); + // ... +}; +``` + +The `useApi` hook always returns a value, or throws an exception if the API ref could not be resolved to a registered implementation. For advanced use cases, where you explicitly want to optionally request a utility API that may or may not have been provided at runtime, you can use the underlying `useApiHolder` hook instead. + +```tsx +import { useApiHolder, configApiRef } from '@backstage/frontend-plugin-api'; + +const MyComponent = () => { + const apis = useApiHolder(); + const configApi = apis.get(configApiRef); // may return undefined + if (configApi) { + const baseUrl = configApi.getString('backend.baseUrl'); + // ... + } +}; +``` + +## Via dependencies + +Your utility APIs can depend on other utility APIs in their factories. You do this by declaring `deps` on your `createApiFactory`, and reading the outcome in your `factory`. + +```tsx +import { + createApiExtension, + createApiFactory, + configApiRef, + discoveryApiRef, +} from '@backstage/frontend-plugin-api'; +import { MyApiImpl } from './MyApiImpl'; + +const myApi = createApiExtension({ + factory: createApiFactory({ + api: myApiRef, + deps: { + configApi: configApiRef, + discoveryApi: discoveryApiRef, + }, + factory: ({ configApi, discoveryApi }) => { + return new MyApiImpl({ configApi, discoveryApi }); + }, + }), +}); +``` + +Note how the `deps` section essentially assigns free-form names that you choose, to API refs. In this example we for example map `configApiRef` to the name `configApi`, but that's just a convention. The framework will ensure that all of those deps get instantiated and passed into your `factory` function with the same set of names as your `deps`. At that point, `configApi` refers to an actual functioning instance of that API ref. diff --git a/docs/frontend-system/utility-apis/04-configuring.md b/docs/frontend-system/utility-apis/04-configuring.md new file mode 100644 index 0000000000..d1de1aa070 --- /dev/null +++ b/docs/frontend-system/utility-apis/04-configuring.md @@ -0,0 +1,25 @@ +--- +id: configuring +title: Configuring Utility APIs +sidebar_label: Configuring +# prettier-ignore +description: Configuring, extending, and overriding utility APIs +--- + +## Adding configurability + +> TODO + +## Configuring + +> TODO + +## Adding extension inputs + +> TODO + +## Adding data to extension inputs + +> TODO + +## Replacing a utility API implementation diff --git a/docs/frontend-system/utility-apis/05-migrating.md b/docs/frontend-system/utility-apis/05-migrating.md new file mode 100644 index 0000000000..0334e80f0b --- /dev/null +++ b/docs/frontend-system/utility-apis/05-migrating.md @@ -0,0 +1,9 @@ +--- +id: migrating +title: Migrating Utility APIs from the old frontend system +sidebar_label: Migrating +# prettier-ignore +description: Migrating Utility APIs from the old frontend system +--- + +> TODO From 716061d7bad05c3e59e20e629a6daaf3dc06a359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Tue, 12 Dec 2023 12:59:19 +0100 Subject: [PATCH 223/275] fix links MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- docs/backend-system/architecture/01-index.md | 2 +- .../architecture/06-utility-apis.md | 30 ++++--------------- docs/frontend-system/utility-apis/01-index.md | 2 +- docs/getting-started/configuration.md | 6 ++-- 4 files changed, 11 insertions(+), 29 deletions(-) diff --git a/docs/backend-system/architecture/01-index.md b/docs/backend-system/architecture/01-index.md index 0e780039b6..6f1a3dd4d1 100644 --- a/docs/backend-system/architecture/01-index.md +++ b/docs/backend-system/architecture/01-index.md @@ -59,7 +59,7 @@ Just like plugins, modules also have access to services and can depend on their A detailed explanation of the package architecture can be found in the [Backstage Architecture -Overview](../../overview/architecture-overview/#package-architecture). The +Overview](../../overview/architecture-overview.md#package-architecture). The most important packages to consider for this system are the following: - `plugin--backend` houses the implementation of the backend plugins diff --git a/docs/frontend-system/architecture/06-utility-apis.md b/docs/frontend-system/architecture/06-utility-apis.md index 4fbbf1af94..bacdcefce2 100644 --- a/docs/frontend-system/architecture/06-utility-apis.md +++ b/docs/frontend-system/architecture/06-utility-apis.md @@ -10,39 +10,21 @@ description: Utility APIs ## Overview -Utility APIs are pieces of standalone functionality, interfaces that can be -requested by plugins to use. They are defined by a TypeScript interface as well -as a reference (an "API ref") used to access its implementation. They can be -provided both by plugins and the core framework, and are themselves -[extensions](../architecture/03-extensions.md) that can have inputs, be -replaced, and be declaratively configured in your app-config. +Utility APIs are pieces of standalone functionality, interfaces that can be requested by plugins to use. They are defined by a TypeScript interface as well as a reference (an "API ref") used to access its implementation. They can be provided both by plugins and the core framework, and are themselves [extensions](../architecture/03-extensions.md) that can have inputs, be replaced, and be declaratively configured in your app-config. -A common example of a utility API is a client interface to interact with the -backend part of a plugin, such as the catalog client. Any frontend plugin can -then request an implementation of that interface to make requests through. +A common example of a utility API is a client interface to interact with the backend part of a plugin, such as the catalog client. Any frontend plugin can then request an implementation of that interface to make requests through. -The following diagram shows a hypothetical application, which depends on two -plugins and also provides some extra overrides. Note that both the plugins and -the core framework exposed utility APIs, and that they depended on each other. -The app also chose to use its overrides mechanism to supply a replacement -implementation of one API, which took precedence over the default one. Thus, all -consumers of that API will be sure to get that new implementation provided to -them. +The following diagram shows a hypothetical application, which depends on two plugins and also provides some extra overrides. Note that both the plugins and the core framework exposed utility APIs, and that they depended on each other. The app also chose to use its overrides mechanism to supply a replacement implementation of one API, which took precedence over the default one. Thus, all consumers of that API will be sure to get that new implementation provided to them. ![frontend system utility apis diagram](../../assets/frontend-system/architecture-utility-apis.drawio.svg) ## Extension structure -All utility APIs implement the `coreExtensionData.apiFactory` output data type, -and must attach exclusively to the `core` extension's `apis` input no matter who -provided them. These defaults are provided out of the box by the -`createApiExtension` framework function. +All utility APIs implement the `coreExtensionData.apiFactory` output data type, and must attach exclusively to the `core` extension's `apis` input no matter who provided them. These defaults are provided out of the box by the `createApiExtension` framework function. -Since utility APIs are extensions, they can also have inputs in advanced use -cases. This is occasionally useful for complex APIs that can themselves be -extended with additional programmatic functionality by adopters. +Since utility APIs are extensions, they can also have inputs in advanced use cases. This is occasionally useful for complex APIs that can themselves be extended with additional programmatic functionality by adopters. ## Links -- The [Using Utility APIs section](../building-plugins/03-utility-apis.md) of the plugin docs +- The [Utility APIs section](../utility-apis/01-index.md) of the plugin docs - The legacy docs on [utility APIs](../../api/utility-apis.md) diff --git a/docs/frontend-system/utility-apis/01-index.md b/docs/frontend-system/utility-apis/01-index.md index 353ad3ffe4..b6eb22706d 100644 --- a/docs/frontend-system/utility-apis/01-index.md +++ b/docs/frontend-system/utility-apis/01-index.md @@ -12,7 +12,7 @@ As described [in the architecture section](../architecture/06-utility-apis.md), > For details, [see the main article](./02-creating.md). -Backstage apps, the core Backstage framework, and plugins can all expose utility APIs for general use. +Backstage apps, plugins, and the core Backstage framework can all expose utility APIs for general use. Some are available out of the box, such as the API for reading app configuration. Some are provided by third party plugins, such as the catalog client API that both the catalog itself and your own code can leverage to talk to the catalog backend. Some, you may create yourself and make available inside your Backstage instance for use within your private ecosystem of plugins. diff --git a/docs/getting-started/configuration.md b/docs/getting-started/configuration.md index b7bf7d448d..019ca254bb 100644 --- a/docs/getting-started/configuration.md +++ b/docs/getting-started/configuration.md @@ -134,7 +134,7 @@ links: There are multiple authentication providers available for you to use with Backstage, feel free to follow -[the instructions for adding authentication](../auth/). +[the instructions for adding authentication](../auth/index.md). For this tutorial we choose to use GitHub, a free service most of you might be familiar with. For other options, see @@ -205,7 +205,7 @@ Restart Backstage from the terminal, by stopping it with `Control-C`, and starti To learn more about Authentication in Backstage, here are some docs you could read: -- [Authentication in Backstage](../auth/) +- [Authentication in Backstage](../auth/index.md) - [Using organizational data from GitHub](../integrations/github/org.md) ### Setting up a GitHub Integration @@ -254,7 +254,7 @@ integrations: Some helpful links, for if you want to learn more about: -- [Other available integrations](../integrations/) +- [Other available integrations](../integrations/index.md) - [Using GitHub Apps instead of a Personal Access Token](../integrations/github/github-apps.md#docsNav) ### Explore what we've done so far From 34ebdb5f199dc0d304d953ef3a90666da108130b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Tue, 12 Dec 2023 16:30:24 +0100 Subject: [PATCH 224/275] flesh out all but the configuration section MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- docs/frontend-system/utility-apis/01-index.md | 10 +- .../utility-apis/02-creating.md | 10 +- .../utility-apis/03-consuming.md | 2 +- .../utility-apis/04-configuring.md | 2 + .../utility-apis/05-migrating.md | 131 +++++++++++++++++- 5 files changed, 143 insertions(+), 12 deletions(-) diff --git a/docs/frontend-system/utility-apis/01-index.md b/docs/frontend-system/utility-apis/01-index.md index b6eb22706d..a6c9f6a784 100644 --- a/docs/frontend-system/utility-apis/01-index.md +++ b/docs/frontend-system/utility-apis/01-index.md @@ -8,7 +8,7 @@ description: Working with Utility APIs in the New Frontend System As described [in the architecture section](../architecture/06-utility-apis.md), utility APIs are pieces of shared functionality - interfaces that can be requested by plugins to use. They are defined by a TypeScript interface as well as a reference (an "API ref") used to access its implementation. They can be provided both by plugins and the core framework, and are themselves [extensions](../architecture/03-extensions.md) that can accept inputs, be declaratively configured in your app-config, or transparently be replaced entirely with custom implementations that fulfill the same contract. -## Creating Utility APIs +## Creating utility APIs > For details, [see the main article](./02-creating.md). @@ -18,7 +18,7 @@ Some are available out of the box, such as the API for reading app configuration [The main article](./02-creating.md) describes the process of creating and exposing utility APIs of your own, for sharing functionality or configurability across plugins and apps. -## Consuming Utility APIs +## Consuming utility APIs > For details, [see the main article](./03-consuming.md). @@ -28,10 +28,14 @@ Some utility APIs in turn depend on other utility APIs. This powerful composabil These are described in detail in [the main article](./03-consuming.md) -## Configuring Utility APIs +## Configuring utility APIs > For details, [see the main article](./04-configuring.md). Most utility APIs are usable directly without any configuration. But they are proper extensions, and can therefore have their implementations entirely swapped out by your app for advanced use cases. They can also be built with the ability to configured in your app-config, or to have inputs that extend their functionality. These cases are all described in [the main article](./04-configuring.md). + +## Migrating from the old frontend system + +If you want to learn how to migrate your own utility APIs from the old frontend system to the new one, that's described in [a dedicated migration guide](./05-migrating.md). diff --git a/docs/frontend-system/utility-apis/02-creating.md b/docs/frontend-system/utility-apis/02-creating.md index 58655a24f5..92bd623744 100644 --- a/docs/frontend-system/utility-apis/02-creating.md +++ b/docs/frontend-system/utility-apis/02-creating.md @@ -62,12 +62,8 @@ const workApi = createApiExtension({ factory: () => createApiFactory({ api: workApiRef, - deps: { - configApi: configApiRef, - }, - factory: ({ configApi }) => { - return new WorkImpl({ configApi }); - }, + deps: { configApi: configApiRef }, + factory: ({ configApi }) => new WorkImpl({ configApi }), }), }); @@ -81,7 +77,7 @@ export default createPlugin({ }); ``` -For illustration we make a skeleton implementation class and the API extension and factory for it, in the same file. These are not exported to the public surface of the plugin package; only the plugin is, as the default export. +For illustration we make a skeleton implementation class and the API extension and factory for it, in the same file. These are not exported to the public surface of the plugin package; only the plugin is, as the default export. Users who install the plugin will now get the utility API automatically as well. The code also illustrates how the API factory declares a dependency on another utility API - the core config API in this case. An instance of that utility API is then provided to the factory function. diff --git a/docs/frontend-system/utility-apis/03-consuming.md b/docs/frontend-system/utility-apis/03-consuming.md index 7c339f1bf9..b24489a21d 100644 --- a/docs/frontend-system/utility-apis/03-consuming.md +++ b/docs/frontend-system/utility-apis/03-consuming.md @@ -43,9 +43,9 @@ Your utility APIs can depend on other utility APIs in their factories. You do th ```tsx import { + configApiRef, createApiExtension, createApiFactory, - configApiRef, discoveryApiRef, } from '@backstage/frontend-plugin-api'; import { MyApiImpl } from './MyApiImpl'; diff --git a/docs/frontend-system/utility-apis/04-configuring.md b/docs/frontend-system/utility-apis/04-configuring.md index d1de1aa070..b56cd10c5c 100644 --- a/docs/frontend-system/utility-apis/04-configuring.md +++ b/docs/frontend-system/utility-apis/04-configuring.md @@ -23,3 +23,5 @@ description: Configuring, extending, and overriding utility APIs > TODO ## Replacing a utility API implementation + +> TODO diff --git a/docs/frontend-system/utility-apis/05-migrating.md b/docs/frontend-system/utility-apis/05-migrating.md index 0334e80f0b..f3e85ceaf4 100644 --- a/docs/frontend-system/utility-apis/05-migrating.md +++ b/docs/frontend-system/utility-apis/05-migrating.md @@ -6,4 +6,133 @@ sidebar_label: Migrating description: Migrating Utility APIs from the old frontend system --- -> TODO +If you are migrating your plugins or app over from the old frontend system, there are a few things to keep in mind in regards to utility APIs. + +## Overview + +- Migrate your repo overall to the latest release of Backstage +- Follow the plugin migration guide +- Change your package dependencies from `core-*-api` to `frontend-*-api` +- Change the imports in your code from `core-*-api` to `frontend-*-api` +- Keep the TypeScript interface and API ref exported as they were, except possibly reconsidering the choice of ID of the latter +- Wrap the old API factory call in an extension using `createApiExtension` +- Make sure that this extension is referenced by your migrated plugin + +## Prerequisites + +This guide assumes that you first [upgrade your repo](../../getting-started/keeping-backstage-updated.md) to the latest release of Backstage. This ensures that you do not have to fight several types of incompatibilities and updates at the same time. + +## Dependency changes + +In this article we will discuss some interfaces that you used to import from the `@backstage/core-plugin-api` package. Those are now generally moved over to `@backstage/frontend-plugin-api`, so you will want to update both your `package.json` and your source code. This applies both in your `-react` package and your main plugin package. + +First `package.json`. The following commands are examples - note that they refer to `plugins/example`, which you'll have to update to the actual folder name that your package to migrate is in. + +```bash title="from your repo root" +yarn --cwd plugins/example remove @backstage/core-plugin-api ; +yarn --cwd plugins/example add @backstage/frontend-plugin-api +``` + +Now in all of the code files in that package: + +```tsx title="in your source code" +/* highlight-remove-next-line */ +import { createApiRef } from '@backstage/core-plugin-api'; +/* highlight-add-next-line */ +import { createApiRef } from '@backstage/frontend-plugin-api'; +``` + +These can typically be search-and-replaced wholesale - the interfaces in the new package are mostly identical to the old one. The `createApiRef` is just an example, and the same replacement makes sense for all of the other symbols from the core package as well. + +## React package interface and ref changes + +Let's begin with [your `-react` package](../../architecture-decisions/adr011-plugin-package-structure.md). The act of exporting TypeScript interfaces and API refs have not changed from the old system. You can typically keep those as-is. For illustrative purposes, this is an example of an interface and its API ref: + +```tsx title="in @internal/plugin-example-react" +import { createApiRef } from '@backstage/frontend-plugin-api'; + +/** + * Performs some work. + * @oublic + */ +export interface WorkApi { + doWork(): Promise; +} + +/** + * The work interface for the Example plugin. + * @public + */ +export const workApiRef = createApiRef({ + id: 'plugin.example.work', +}); +``` + +In this example, the plugin ID already follows the common naming convention. If it doesn't, you may want to consider renaming that ID at this point. Don't worry, this won't hurt consumers in the old frontend system since the ID is mostly used for debugging purposes there. In the new system, it's much more important and appears in app-config files and similar. + +Note at the top of the file that it uses the updated import from `@backstage/frontend-plugin-api` that we migrated in the previous section, instead of the old `@backstage/core-plugin-api`. + +## Plugin package changes + +Now let's turn to the main plugin package where the plugin itself is exported. You will probably already have a `createPlugin` call in here. Before we changed the `core-plugin-api` imports it'll have looked somewhat similar to the following: + +```tsx title="in @internal/plugin-example, NOTE THIS IS LEGACY CODE" +import { + configApiRef, + createPlugin, + createApiFactory, +} from '@backstage/core-plugin-api'; +import { workApiRef } from '@internal/plugin-example-react'; +import { WorkImpl } from './WorkImpl'; + +const workApi = createApiFactory({ + api: workApiRef, + deps: { configApi: configApiRef }, + factory: ({ configApi }) => new WorkImpl({ configApi }), +}); + +/** @public */ +export const catalogPlugin = createPlugin({ + id: 'example', + apis: [workApi], +}); +``` + +The major changes we'll make are + +- Change the import to the new package as per the top section of this guide +- Wrap the existing API factory in a `createApiExtension` +- Change to the new version of `createPlugin` which exports this extension +- Change the plugin export to be the default instead + +```tsx title="in @internal/plugin-example" +import { + configApiRef, + createPlugin, + createApiFactory, + createApiExtension, +} from '@backstage/frontend-plugin-api'; +import { workApiRef } from '@internal/plugin-example-react'; +import { WorkImpl } from './WorkImpl'; + +const workApi = createApiExtension({ + api: workApiRef, + factory: () => + // The factory itself is unchanged + createApiFactory({ + api: workApiRef, + deps: { configApi: configApiRef }, + factory: ({ configApi }) => new WorkImpl({ configApi }), + }), +}); + +/** @public */ +export default createPlugin({ + id: 'example', + extensions: [workApi], +}); +``` + +## Further work + +Since utility APIs are now complete extensions, you may want to take a bigger look at how they used to be used, and what the new frontend system offers. You may for example consider [adding configurability or inputs](./04-configuring.md) to your API, if that makes sense for your current application. From 8568feabdf633b71a131b5a0af2e0abd8a1f7530 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Wed, 13 Dec 2023 16:04:17 +0100 Subject: [PATCH 225/275] begin on the configuring section MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .../utility-apis/02-creating.md | 12 ++-- .../utility-apis/03-consuming.md | 2 +- .../utility-apis/04-configuring.md | 57 ++++++++++++++++++- .../utility-apis/05-migrating.md | 12 ++-- 4 files changed, 69 insertions(+), 14 deletions(-) diff --git a/docs/frontend-system/utility-apis/02-creating.md b/docs/frontend-system/utility-apis/02-creating.md index 92bd623744..9d71d3ba14 100644 --- a/docs/frontend-system/utility-apis/02-creating.md +++ b/docs/frontend-system/utility-apis/02-creating.md @@ -43,13 +43,13 @@ import { createApiExtension, createApiFactory, createPlugin, - configApiRef, - ConfigApi, + storageApiRef, + StorageApi, } from '@backstage/frontend-plugin-api'; import { WorkApi, workApiRef } from '@internal/plugin-example-react'; class WorkImpl implements WorkApi { - constructor(options: { configApi: ConfigApi }) { + constructor(options: { storageApiRef: StorageApi }) { /* TODO */ } async doWork() { @@ -62,8 +62,8 @@ const workApi = createApiExtension({ factory: () => createApiFactory({ api: workApiRef, - deps: { configApi: configApiRef }, - factory: ({ configApi }) => new WorkImpl({ configApi }), + deps: { storageApi: storageApiRef }, + factory: ({ storageApi }) => new WorkImpl({ storageApi }), }), }); @@ -79,7 +79,7 @@ export default createPlugin({ For illustration we make a skeleton implementation class and the API extension and factory for it, in the same file. These are not exported to the public surface of the plugin package; only the plugin is, as the default export. Users who install the plugin will now get the utility API automatically as well. -The code also illustrates how the API factory declares a dependency on another utility API - the core config API in this case. An instance of that utility API is then provided to the factory function. +The code also illustrates how the API factory declares a dependency on another utility API - the core storage API in this case. An instance of that utility API is then provided to the factory function. The resulting extension ID of the work API will be the kind `api:` followed by the plugin ID as the namespace, in this case ending up as `api:plugin.example.work`. You can now use this ID to refer to the API in app-config and elsewhere. diff --git a/docs/frontend-system/utility-apis/03-consuming.md b/docs/frontend-system/utility-apis/03-consuming.md index b24489a21d..006f3b8fab 100644 --- a/docs/frontend-system/utility-apis/03-consuming.md +++ b/docs/frontend-system/utility-apis/03-consuming.md @@ -64,4 +64,4 @@ const myApi = createApiExtension({ }); ``` -Note how the `deps` section essentially assigns free-form names that you choose, to API refs. In this example we for example map `configApiRef` to the name `configApi`, but that's just a convention. The framework will ensure that all of those deps get instantiated and passed into your `factory` function with the same set of names as your `deps`. At that point, `configApi` refers to an actual functioning instance of that API ref. +Note how the `deps` section essentially assigns free-form names that you choose, to API refs. Here we for example map `configApiRef` to the name `configApi`, but that's just a convention. The framework will ensure that all of those deps get instantiated and passed into your `factory` function with the same set of names as your `deps`. At that point, `configApi` refers to an actual functioning instance of that API ref. diff --git a/docs/frontend-system/utility-apis/04-configuring.md b/docs/frontend-system/utility-apis/04-configuring.md index b56cd10c5c..d6b6167ca2 100644 --- a/docs/frontend-system/utility-apis/04-configuring.md +++ b/docs/frontend-system/utility-apis/04-configuring.md @@ -6,9 +6,64 @@ sidebar_label: Configuring description: Configuring, extending, and overriding utility APIs --- +Utility APIs are extensions and can therefore optionally be amended with configurability, as well as inputs that other extensions attach themselves to. This section describes how to add those capabilities to your own utility APIs, and how to make use of them as a consumer of such utility APIs. + ## Adding configurability -> TODO +Here we will describe how to amend a utility API with the capability of being configured in app-config. You do this by giving a config schema to your API extension factory function. + +Let's make the required additions to [our original work example](./02-creating.md) API. + +```tsx title="in @internal/plugin-example" +import { + createApiExtension, + createApiFactory, + createPlugin, + /* highlight-add-next-line */ + createSchemaFromZod, + storageApiRef, + StorageApi, +} from '@backstage/frontend-plugin-api'; +import { WorkApi, workApiRef } from '@internal/plugin-example-react'; + +/* highlight-add-start */ +interface WorkApiConfig { + goSlow: boolean; +} +/* highlight-add-end */ + +const workApi = createApiExtension({ + api: workApiRef, + /* highlight-add-start */ + configSchema: createSchemaFromZod(z => + z.object({ + goSlow: z.boolean().default(false), + }), + ), + /* highlight-add-end */ + /* highlight-remove-next-line */ + factory: () => + /* highlight-add-next-line */ + factory: ({ config }) => + createApiFactory({ + api: workApiRef, + deps: { storageApi: storageApiRef }, + factory: ({ storageApi }) => { + /* highlight-add-start */ + if (config.goSlow) { + /* ... */ + } + /* highlight-add-end */ + }, + }), +}); +``` + +We wanted users to be able to configure a `goSlow` parameter for our API instances. So we added another interface type for holding our various options, and passed in a `configSchema` to `createApiExtension` which matches that interface. This example builds it using [the zod library](https://zod.dev/). The actual config values will then be passed in to the `factory` callback, where we can do what we wish with them. + +Note that while we use the word "config" here, it's _not_ the same thing as the `configApi` which gives you access to the full app-config. The config discussed here is instead the particular configuration settings given to your utility API instance. This is discussed more [in the section below](#configuring). + +Note also that the config schema contained a default value fo the `goSlow` field. This is an important consideration. You want users of your API to be able to make maximum use of it, without having to dive deep into how to configure it. For that reason you generally want to provide as many sane defaults as possible, while letting users override them rarely but with purpose, only when called for. If you have a config schema without defaults, the framework will refuse to instantiate the utility API on startup unless the user had configured those values explicitly. Since it had a default value, the TypeScript code and interfaces also don't have to defensively allow `undefined` - we know that it'll have either the default value or an overridden value when we start consuming the config data. ## Configuring diff --git a/docs/frontend-system/utility-apis/05-migrating.md b/docs/frontend-system/utility-apis/05-migrating.md index f3e85ceaf4..b4b456e65f 100644 --- a/docs/frontend-system/utility-apis/05-migrating.md +++ b/docs/frontend-system/utility-apis/05-migrating.md @@ -78,7 +78,7 @@ Now let's turn to the main plugin package where the plugin itself is exported. Y ```tsx title="in @internal/plugin-example, NOTE THIS IS LEGACY CODE" import { - configApiRef, + storageApiRef, createPlugin, createApiFactory, } from '@backstage/core-plugin-api'; @@ -87,8 +87,8 @@ import { WorkImpl } from './WorkImpl'; const workApi = createApiFactory({ api: workApiRef, - deps: { configApi: configApiRef }, - factory: ({ configApi }) => new WorkImpl({ configApi }), + deps: { storageApi: storageApiRef }, + factory: ({ storageApi }) => new WorkImpl({ storageApi }), }); /** @public */ @@ -107,7 +107,7 @@ The major changes we'll make are ```tsx title="in @internal/plugin-example" import { - configApiRef, + storageApiRef, createPlugin, createApiFactory, createApiExtension, @@ -121,8 +121,8 @@ const workApi = createApiExtension({ // The factory itself is unchanged createApiFactory({ api: workApiRef, - deps: { configApi: configApiRef }, - factory: ({ configApi }) => new WorkImpl({ configApi }), + deps: { storageApi: storageApiRef }, + factory: ({ storageApi }) => new WorkImpl({ storageApi }), }), }); From 7da59f36bd3bef0009fb9f8143813a6549bee057 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Fri, 15 Dec 2023 14:55:40 +0100 Subject: [PATCH 226/275] Update docs/frontend-system/architecture/06-utility-apis.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Patrik Oldsberg Signed-off-by: Fredrik Adelöw --- docs/frontend-system/architecture/06-utility-apis.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/06-utility-apis.md b/docs/frontend-system/architecture/06-utility-apis.md index bacdcefce2..9b380ae592 100644 --- a/docs/frontend-system/architecture/06-utility-apis.md +++ b/docs/frontend-system/architecture/06-utility-apis.md @@ -14,7 +14,7 @@ Utility APIs are pieces of standalone functionality, interfaces that can be requ A common example of a utility API is a client interface to interact with the backend part of a plugin, such as the catalog client. Any frontend plugin can then request an implementation of that interface to make requests through. -The following diagram shows a hypothetical application, which depends on two plugins and also provides some extra overrides. Note that both the plugins and the core framework exposed utility APIs, and that they depended on each other. The app also chose to use its overrides mechanism to supply a replacement implementation of one API, which took precedence over the default one. Thus, all consumers of that API will be sure to get that new implementation provided to them. +The following diagram shows a hypothetical application, which depends on two plugins and also provides some extra overrides. Note that both the plugins and the core framework provide utility APIs, and that they depended on each other. The app also choses to use its overrides mechanism to supply a replacement implementation of one API, which takes precedence over the default one. Thus, all consumers of that API will be sure to get that new implementation provided to them. ![frontend system utility apis diagram](../../assets/frontend-system/architecture-utility-apis.drawio.svg) From 812fc5440512e04a459c647ead9894d42226165d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Fri, 15 Dec 2023 14:56:17 +0100 Subject: [PATCH 227/275] Update docs/frontend-system/utility-apis/02-creating.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Patrik Oldsberg Signed-off-by: Fredrik Adelöw --- docs/frontend-system/utility-apis/02-creating.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/utility-apis/02-creating.md b/docs/frontend-system/utility-apis/02-creating.md index 9d71d3ba14..5e940ca678 100644 --- a/docs/frontend-system/utility-apis/02-creating.md +++ b/docs/frontend-system/utility-apis/02-creating.md @@ -12,7 +12,7 @@ description: Creating new utility APIs in your plugins and app ## Creating the Utility API contract -The first step toward exposing a utility API is to define its TypeScript contract, and an API ref for consumers to find it via. This should be done in [your plugin's `-react` package](../../architecture-decisions/adr011-plugin-package-structure.md), so that it can be imported by other plugins. In this example, we have an Example plugin that wants to expose a utility API for performing some type of work. +The first step toward exposing a utility API is to define its TypeScript contract, as well as an API reference for consumers use to access the implementation. If you want your API to be accessible by other plugins this should be done in [your plugin's `-react` package](../../architecture-decisions/adr011-plugin-package-structure.md), so that it can be imported separately. If you just want to use the API within your own plugin it is fine to place the definition within the plugin itself. In this example, we have an Example plugin that wants to expose a utility API for performing some type of work. ```tsx title="in @internal/plugin-example-react" import { createApiRef } from '@backstage/frontend-plugin-api'; From 9bc836cc579b950aec67ccfa537244f710919b8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Fri, 15 Dec 2023 14:56:41 +0100 Subject: [PATCH 228/275] Update docs/frontend-system/architecture/06-utility-apis.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Patrik Oldsberg Signed-off-by: Fredrik Adelöw --- docs/frontend-system/architecture/06-utility-apis.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/06-utility-apis.md b/docs/frontend-system/architecture/06-utility-apis.md index 9b380ae592..ff106e2ea6 100644 --- a/docs/frontend-system/architecture/06-utility-apis.md +++ b/docs/frontend-system/architecture/06-utility-apis.md @@ -20,7 +20,7 @@ The following diagram shows a hypothetical application, which depends on two plu ## Extension structure -All utility APIs implement the `coreExtensionData.apiFactory` output data type, and must attach exclusively to the `core` extension's `apis` input no matter who provided them. These defaults are provided out of the box by the `createApiExtension` framework function. +All utility APIs implement the `createApiExtension.factoryDataRef` output data type, and must attach exclusively to the `core` extension's `apis` input no matter who provided them. These defaults are provided out of the box by the `createApiExtension` framework function. Since utility APIs are extensions, they can also have inputs in advanced use cases. This is occasionally useful for complex APIs that can themselves be extended with additional programmatic functionality by adopters. From 67b15262f101e3f74923edee892e52604f9e1e84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Fri, 15 Dec 2023 14:57:44 +0100 Subject: [PATCH 229/275] Update docs/frontend-system/utility-apis/02-creating.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Patrik Oldsberg Signed-off-by: Fredrik Adelöw --- docs/frontend-system/utility-apis/02-creating.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/docs/frontend-system/utility-apis/02-creating.md b/docs/frontend-system/utility-apis/02-creating.md index 5e940ca678..e56220841c 100644 --- a/docs/frontend-system/utility-apis/02-creating.md +++ b/docs/frontend-system/utility-apis/02-creating.md @@ -57,14 +57,12 @@ class WorkImpl implements WorkApi { } } -const workApi = createApiExtension({ - api: workApiRef, - factory: () => - createApiFactory({ - api: workApiRef, - deps: { storageApi: storageApiRef }, - factory: ({ storageApi }) => new WorkImpl({ storageApi }), - }), +const exampleWorkApi = createApiExtension({ + factory: createApiFactory({ + api: workApiRef, + deps: { storageApi: storageApiRef }, + factory: ({ storageApi }) => new WorkImpl({ storageApi }), + }), }); /** From 8d469f8991b9487c1f44bfc09d4422a67e4f6c2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Fri, 15 Dec 2023 14:58:42 +0100 Subject: [PATCH 230/275] Update docs/frontend-system/utility-apis/02-creating.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Patrik Oldsberg Signed-off-by: Fredrik Adelöw --- docs/frontend-system/utility-apis/02-creating.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/frontend-system/utility-apis/02-creating.md b/docs/frontend-system/utility-apis/02-creating.md index e56220841c..49fce0b307 100644 --- a/docs/frontend-system/utility-apis/02-creating.md +++ b/docs/frontend-system/utility-apis/02-creating.md @@ -18,15 +18,19 @@ The first step toward exposing a utility API is to define its TypeScript contrac import { createApiRef } from '@backstage/frontend-plugin-api'; /** - * Performs some work. - * @oublic + * The work interface for the Example plugin. + * @public */ export interface WorkApi { + /** + * Performs some work. + * @public + */ doWork(): Promise; } /** - * The work interface for the Example plugin. + * API Reference for {@link WorkApi}. * @public */ export const workApiRef = createApiRef({ From 2c0ef3f119ad7e81fde233e1dff901866a88d173 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Fri, 15 Dec 2023 14:59:01 +0100 Subject: [PATCH 231/275] Update docs/frontend-system/utility-apis/02-creating.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Patrik Oldsberg Signed-off-by: Fredrik Adelöw --- docs/frontend-system/utility-apis/02-creating.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/utility-apis/02-creating.md b/docs/frontend-system/utility-apis/02-creating.md index 49fce0b307..4f6c329df7 100644 --- a/docs/frontend-system/utility-apis/02-creating.md +++ b/docs/frontend-system/utility-apis/02-creating.md @@ -75,7 +75,7 @@ const exampleWorkApi = createApiExtension({ */ export default createPlugin({ id: 'example', - extensions: [workApi], + extensions: [exampleWorkApi], }); ``` From cc6ccb5e11c61a7f4eeaff4ee90638793850f338 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Fri, 15 Dec 2023 15:41:28 +0100 Subject: [PATCH 232/275] review fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .../architecture/06-utility-apis.md | 2 +- .../utility-apis/03-consuming.md | 4 +-- .../utility-apis/04-configuring.md | 29 ++++++++-------- .../utility-apis/05-migrating.md | 34 +++++-------------- 4 files changed, 26 insertions(+), 43 deletions(-) diff --git a/docs/frontend-system/architecture/06-utility-apis.md b/docs/frontend-system/architecture/06-utility-apis.md index ff106e2ea6..c0b65a840b 100644 --- a/docs/frontend-system/architecture/06-utility-apis.md +++ b/docs/frontend-system/architecture/06-utility-apis.md @@ -14,7 +14,7 @@ Utility APIs are pieces of standalone functionality, interfaces that can be requ A common example of a utility API is a client interface to interact with the backend part of a plugin, such as the catalog client. Any frontend plugin can then request an implementation of that interface to make requests through. -The following diagram shows a hypothetical application, which depends on two plugins and also provides some extra overrides. Note that both the plugins and the core framework provide utility APIs, and that they depended on each other. The app also choses to use its overrides mechanism to supply a replacement implementation of one API, which takes precedence over the default one. Thus, all consumers of that API will be sure to get that new implementation provided to them. +The following diagram shows a hypothetical application, which depends on two plugins and also provides some extra overrides. Note that both the plugins and the core framework provide utility APIs, and that they depended on each other. The app also chooses to use its overrides mechanism to supply a replacement implementation of one API, which takes precedence over the default one. Thus, all consumers of that API will be sure to get that new implementation provided to them. ![frontend system utility apis diagram](../../assets/frontend-system/architecture-utility-apis.drawio.svg) diff --git a/docs/frontend-system/utility-apis/03-consuming.md b/docs/frontend-system/utility-apis/03-consuming.md index 006f3b8fab..4748cc786a 100644 --- a/docs/frontend-system/utility-apis/03-consuming.md +++ b/docs/frontend-system/utility-apis/03-consuming.md @@ -17,7 +17,7 @@ import { useApi, configApiRef } from '@backstage/frontend-plugin-api'; const MyComponent = () => { const configApi = useApi(configApiRef); - const baseUrl = configApi.getString('backend.baseUrl'); + const title = configApi.getString('app.title'); // ... }; ``` @@ -31,7 +31,7 @@ const MyComponent = () => { const apis = useApiHolder(); const configApi = apis.get(configApiRef); // may return undefined if (configApi) { - const baseUrl = configApi.getString('backend.baseUrl'); + const title = configApi.getString('app.title'); // ... } }; diff --git a/docs/frontend-system/utility-apis/04-configuring.md b/docs/frontend-system/utility-apis/04-configuring.md index d6b6167ca2..334fb4d6b5 100644 --- a/docs/frontend-system/utility-apis/04-configuring.md +++ b/docs/frontend-system/utility-apis/04-configuring.md @@ -33,8 +33,8 @@ interface WorkApiConfig { /* highlight-add-end */ const workApi = createApiExtension({ - api: workApiRef, /* highlight-add-start */ + api: workApiRef, configSchema: createSchemaFromZod(z => z.object({ goSlow: z.boolean().default(false), @@ -42,24 +42,23 @@ const workApi = createApiExtension({ ), /* highlight-add-end */ /* highlight-remove-next-line */ - factory: () => + factory: createApiFactory({ /* highlight-add-next-line */ - factory: ({ config }) => - createApiFactory({ - api: workApiRef, - deps: { storageApi: storageApiRef }, - factory: ({ storageApi }) => { - /* highlight-add-start */ - if (config.goSlow) { - /* ... */ - } - /* highlight-add-end */ - }, - }), + factory: ({ config }) => createApiFactory({ + api: workApiRef, + deps: { storageApi: storageApiRef }, + factory: ({ storageApi }) => { + /* highlight-add-start */ + if (config.goSlow) { + /* ... */ + } + /* highlight-add-end */ + }, + }), }); ``` -We wanted users to be able to configure a `goSlow` parameter for our API instances. So we added another interface type for holding our various options, and passed in a `configSchema` to `createApiExtension` which matches that interface. This example builds it using [the zod library](https://zod.dev/). The actual config values will then be passed in to the `factory` callback, where we can do what we wish with them. +We wanted users to be able to configure a `goSlow` parameter for our API instances. So we added another interface type for holding our various options, and passed in a `configSchema` to `createApiExtension` which matches that interface. This example builds it using [the zod library](https://zod.dev/). The actual config values will then be passed in to the `factory` which is now a callback, wherein we can do what we wish with them. When changing to the callback form, we also had to add a top level `api: workApiRef` under `createApiExtension`. Note that while we use the word "config" here, it's _not_ the same thing as the `configApi` which gives you access to the full app-config. The config discussed here is instead the particular configuration settings given to your utility API instance. This is discussed more [in the section below](#configuring). diff --git a/docs/frontend-system/utility-apis/05-migrating.md b/docs/frontend-system/utility-apis/05-migrating.md index b4b456e65f..b8cb50c224 100644 --- a/docs/frontend-system/utility-apis/05-migrating.md +++ b/docs/frontend-system/utility-apis/05-migrating.md @@ -12,8 +12,7 @@ If you are migrating your plugins or app over from the old frontend system, ther - Migrate your repo overall to the latest release of Backstage - Follow the plugin migration guide -- Change your package dependencies from `core-*-api` to `frontend-*-api` -- Change the imports in your code from `core-*-api` to `frontend-*-api` +- Optionally change your package dependencies and code from `core-*-api` to `frontend-*-api` - Keep the TypeScript interface and API ref exported as they were, except possibly reconsidering the choice of ID of the latter - Wrap the old API factory call in an extension using `createApiExtension` - Make sure that this extension is referenced by your migrated plugin @@ -24,26 +23,14 @@ This guide assumes that you first [upgrade your repo](../../getting-started/keep ## Dependency changes -In this article we will discuss some interfaces that you used to import from the `@backstage/core-plugin-api` package. Those are now generally moved over to `@backstage/frontend-plugin-api`, so you will want to update both your `package.json` and your source code. This applies both in your `-react` package and your main plugin package. +In this article we will discuss some old interfaces that you used to import from the `@backstage/core-plugin-api` package. Those are now generally lifted over to `@backstage/frontend-plugin-api`, next to the new interfaces that are specific to the new frontend system. If you want to, you can already update your `package.json` and code imports to only use the new plugin API, but for the time being you don't have to. The old core exports will continue to work for the foreseeable future. -First `package.json`. The following commands are examples - note that they refer to `plugins/example`, which you'll have to update to the actual folder name that your package to migrate is in. +To at least get access to the new interfaces, you'll need to run the following command. Note that it's just an example! It refers to `plugins/example`, which you'll have to change to the actual folder name that your package to migrate is in. ```bash title="from your repo root" -yarn --cwd plugins/example remove @backstage/core-plugin-api ; yarn --cwd plugins/example add @backstage/frontend-plugin-api ``` -Now in all of the code files in that package: - -```tsx title="in your source code" -/* highlight-remove-next-line */ -import { createApiRef } from '@backstage/core-plugin-api'; -/* highlight-add-next-line */ -import { createApiRef } from '@backstage/frontend-plugin-api'; -``` - -These can typically be search-and-replaced wholesale - the interfaces in the new package are mostly identical to the old one. The `createApiRef` is just an example, and the same replacement makes sense for all of the other symbols from the core package as well. - ## React package interface and ref changes Let's begin with [your `-react` package](../../architecture-decisions/adr011-plugin-package-structure.md). The act of exporting TypeScript interfaces and API refs have not changed from the old system. You can typically keep those as-is. For illustrative purposes, this is an example of an interface and its API ref: @@ -100,7 +87,7 @@ export const catalogPlugin = createPlugin({ The major changes we'll make are -- Change the import to the new package as per the top section of this guide +- Optionally change the old imports to the new package as per the top section of this guide - Wrap the existing API factory in a `createApiExtension` - Change to the new version of `createPlugin` which exports this extension - Change the plugin export to be the default instead @@ -116,14 +103,11 @@ import { workApiRef } from '@internal/plugin-example-react'; import { WorkImpl } from './WorkImpl'; const workApi = createApiExtension({ - api: workApiRef, - factory: () => - // The factory itself is unchanged - createApiFactory({ - api: workApiRef, - deps: { storageApi: storageApiRef }, - factory: ({ storageApi }) => new WorkImpl({ storageApi }), - }), + factory: createApiFactory({ + api: workApiRef, + deps: { storageApi: storageApiRef }, + factory: ({ storageApi }) => new WorkImpl({ storageApi }), + }), }); /** @public */ From 60ed1d935b6b2964b495dc6500267f479ed0a765 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Fri, 15 Dec 2023 16:17:36 +0100 Subject: [PATCH 233/275] flesh out the api docs some more MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .../utility-apis/02-creating.md | 67 +++++++++-- .../utility-apis/04-configuring.md | 111 ++++++++---------- .../utility-apis/05-migrating.md | 12 +- 3 files changed, 119 insertions(+), 71 deletions(-) diff --git a/docs/frontend-system/utility-apis/02-creating.md b/docs/frontend-system/utility-apis/02-creating.md index 4f6c329df7..4b87a1dfe0 100644 --- a/docs/frontend-system/utility-apis/02-creating.md +++ b/docs/frontend-system/utility-apis/02-creating.md @@ -6,9 +6,7 @@ sidebar_label: Creating APIs description: Creating new utility APIs in your plugins and app --- -## When to make a utility API - -> TODO +This section describes how to make a Utility API from scratch, or to add configurability and inputs to an existing one. If you are instead interested in migrating an existing Utility API from the old frontend system, check out [the migrating section](./05-migrating.md). ## Creating the Utility API contract @@ -24,7 +22,6 @@ import { createApiRef } from '@backstage/frontend-plugin-api'; export interface WorkApi { /** * Performs some work. - * @public */ doWork(): Promise; } @@ -40,6 +37,8 @@ export const workApiRef = createApiRef({ Both of these are properly exported publicly from the package, so that consumers can reach them. +## Providing an extension through your plugin + The plugin itself now wants to provide this API and its default implementation, in the form of an API extension. Doing so means that when users install the Example plugin, an instance of the Work utility API will also be automatically available in their apps - both to the Example plugin itself, and to others. We do this in the main plugin package, not the `-react` package. ```tsx title="in @internal/plugin-example" @@ -65,7 +64,9 @@ const exampleWorkApi = createApiExtension({ factory: createApiFactory({ api: workApiRef, deps: { storageApi: storageApiRef }, - factory: ({ storageApi }) => new WorkImpl({ storageApi }), + factory: ({ storageApi }) => { + return new WorkImpl({ storageApi }); + }, }), }); @@ -83,8 +84,60 @@ For illustration we make a skeleton implementation class and the API extension a The code also illustrates how the API factory declares a dependency on another utility API - the core storage API in this case. An instance of that utility API is then provided to the factory function. -The resulting extension ID of the work API will be the kind `api:` followed by the plugin ID as the namespace, in this case ending up as `api:plugin.example.work`. You can now use this ID to refer to the API in app-config and elsewhere. +The resulting extension ID of the work API will be the kind `api:` followed by the plugin ID as the namespace, in this case ending up as `api:plugin.example.work`. Check out [the naming patterns doc](../architecture/08-naming-patterns.md) for more information on how this works. You can now use this ID to refer to the API in app-config and elsewhere. + +## Adding configurability + +Here we will describe how to amend a utility API with the capability of being configured in app-config. You do this by giving a config schema to your API extension factory function. Let's make the required additions to our original work example API. + +```tsx title="in @internal/plugin-example" +/* highlight-add-next-line */ +import { createSchemaFromZod } from '@backstage/frontend-plugin-api'; + +const exampleWorkApi = createApiExtension({ + /* highlight-add-start */ + api: workApiRef, + configSchema: createSchemaFromZod(z => + z.object({ + goSlow: z.boolean().default(false), + }), + ), + /* highlight-add-end */ + /* highlight-remove-next-line */ + factory: createApiFactory({ + /* highlight-add-next-line */ + factory: ({ config }) => createApiFactory({ + api: workApiRef, + deps: { storageApi: storageApiRef }, + factory: ({ storageApi }) => { + /* highlight-add-start */ + if (config.goSlow) { + /* ... */ + } + /* highlight-add-end */ + }, + }), +}); +``` + +We wanted users to be able to configure a `goSlow` parameter for our API instances. So we passed in a `configSchema` to `createApiExtension` which matches that interface. This example builds it using [the zod library](https://zod.dev/). The actual config values will then be passed in a type safe manner in to the `factory` which is now a callback, wherein we can do what we wish with them. When changing to the callback form, we also had to add a top level `api: workApiRef` under `createApiExtension`. + +Note that while we use the word "config" here, it's _not_ the same thing as the `configApi` which gives you access to the full app-config. The config discussed here is instead the particular configuration settings given to your utility API instance. This is discussed more [in the Configuring section below](./04-configuring.md). + +Note also that the config schema contained a default value fo the `goSlow` field. This is an important consideration. You want users of your API to be able to make maximum use of it, without having to dive deep into how to configure it. For that reason you generally want to provide as many sane defaults as possible, while letting users override them rarely but with purpose, only when called for. If you have a config schema without defaults, the framework will refuse to instantiate the utility API on startup unless the user had configured those values explicitly. Since it had a default value, the TypeScript code and interfaces also don't have to defensively allow `undefined` - we know that it'll have either the default value or an overridden value when we start consuming the config data. + +## Adding inputs + +Inputs are added to Utility APIs in the same way as other extension types: + +- Declaring a set of `inputs` on your extension +- If needed, create custom extension data types to be used in those inputs +- If needed, export an extension creator function for creating that particular attachment type + +This is a power use case and not very commonly used. + + ## Next steps -See [the Consuming section](./03-consuming.md) to see how to consume this new utility API in various ways. If you wish to learn how to add configurability and inputs to it, check out [the Configuring section](./04-configuring.md). +See [the Consuming section](./03-consuming.md) to see how to consume this new utility API in various ways. If you wish to configure and add inputs to it, check out [the Configuring section](./04-configuring.md). diff --git a/docs/frontend-system/utility-apis/04-configuring.md b/docs/frontend-system/utility-apis/04-configuring.md index 334fb4d6b5..602caf0efc 100644 --- a/docs/frontend-system/utility-apis/04-configuring.md +++ b/docs/frontend-system/utility-apis/04-configuring.md @@ -8,74 +8,67 @@ description: Configuring, extending, and overriding utility APIs Utility APIs are extensions and can therefore optionally be amended with configurability, as well as inputs that other extensions attach themselves to. This section describes how to add those capabilities to your own utility APIs, and how to make use of them as a consumer of such utility APIs. -## Adding configurability +## Configuring -Here we will describe how to amend a utility API with the capability of being configured in app-config. You do this by giving a config schema to your API extension factory function. +To configure your Utility API extension, first you'll need to know its ID. That ID is formed from the API ref ID; check [the naming patterns docs](../architecture/08-naming-patterns.md) for details. -Let's make the required additions to [our original work example](./02-creating.md) API. +Our example work API from [the creating section](./02-creating.md) would have the ID `api:plugin.example.work`. You configure it and all other extensions under the `app.extensions` section of your app-config. -```tsx title="in @internal/plugin-example" -import { - createApiExtension, - createApiFactory, - createPlugin, - /* highlight-add-next-line */ - createSchemaFromZod, - storageApiRef, - StorageApi, -} from '@backstage/frontend-plugin-api'; -import { WorkApi, workApiRef } from '@internal/plugin-example-react'; +```yaml title="in e.g. app-config.yaml or app-config.production.yaml" +app: + extensions: + - api:plugin.example.work: + config: + goSlow: false + - # ... other extensions +``` +It's important to note that the `extensions` are a list (mind the initial `-`), and that the `api:plugin.example.work` entry is an object such that the `config` key needs to be indented below it. If you do not get those two pieces right, the application may not start up correctly. + +The config schema of the extension will tell you what configuration parameters it supports. Here we override the `goSlow` configuration value, which replaces the default. + +## Attaching extensions to inputs + +Like with other extension types, you add input attachments to a Utility API by declaring the `attachTo` section of that attachment to point to the Utility APIs ID and input name. + +Well written input-enabled extension often have extension creator functions that help you make such attachments. Those functions typically set the `attachTo` section correctly on your behalf so that you don't have to figure them out. + +## Replacing a Utility API implementation + +Like with other extension types, you replace Utility APIs with your own custom implementation using [extension overrides](../architecture/05-extension-overrides.md). + +```tsx title="in your app" /* highlight-add-start */ -interface WorkApiConfig { - goSlow: boolean; +import { createExtensionOverrides } from '@backstage/frontend-plugin-api'; + +class CustomWorkImpl implements WorkApi { + /* ... */ } + +const myOverrides = createExtensionOverrides({ + extensions: [ + createApiExtension({ + api: workApiRef, + factory: () => + createApiFactory({ + api: workApiRef, + factory: () => new CustomWorkImpl(), + }), + }), + ], +}); /* highlight-add-end */ -const workApi = createApiExtension({ - /* highlight-add-start */ - api: workApiRef, - configSchema: createSchemaFromZod(z => - z.object({ - goSlow: z.boolean().default(false), - }), - ), - /* highlight-add-end */ - /* highlight-remove-next-line */ - factory: createApiFactory({ - /* highlight-add-next-line */ - factory: ({ config }) => createApiFactory({ - api: workApiRef, - deps: { storageApi: storageApiRef }, - factory: ({ storageApi }) => { - /* highlight-add-start */ - if (config.goSlow) { - /* ... */ - } - /* highlight-add-end */ - }, - }), +// Remember to pass the overrides to your createApp +export default createApp({ + features: [ + // ... other features + /* highlight-add-next-line */ + myOverrides, + ], }); ``` -We wanted users to be able to configure a `goSlow` parameter for our API instances. So we added another interface type for holding our various options, and passed in a `configSchema` to `createApiExtension` which matches that interface. This example builds it using [the zod library](https://zod.dev/). The actual config values will then be passed in to the `factory` which is now a callback, wherein we can do what we wish with them. When changing to the callback form, we also had to add a top level `api: workApiRef` under `createApiExtension`. +In this example the overriding extension is kept minimal, but just like any other extension it can also have `deps`, configurability, and inputs. Check out [the Creating section](./02-creating.md) for more details about that. -Note that while we use the word "config" here, it's _not_ the same thing as the `configApi` which gives you access to the full app-config. The config discussed here is instead the particular configuration settings given to your utility API instance. This is discussed more [in the section below](#configuring). - -Note also that the config schema contained a default value fo the `goSlow` field. This is an important consideration. You want users of your API to be able to make maximum use of it, without having to dive deep into how to configure it. For that reason you generally want to provide as many sane defaults as possible, while letting users override them rarely but with purpose, only when called for. If you have a config schema without defaults, the framework will refuse to instantiate the utility API on startup unless the user had configured those values explicitly. Since it had a default value, the TypeScript code and interfaces also don't have to defensively allow `undefined` - we know that it'll have either the default value or an overridden value when we start consuming the config data. - -## Configuring - -> TODO - -## Adding extension inputs - -> TODO - -## Adding data to extension inputs - -> TODO - -## Replacing a utility API implementation - -> TODO +When you create a replacement extension, in general you may want to mimic its config schema or input shapes where applicable. This makes it an easier thing to slot in to an app, since it'll be responding to extensibility the same way as the original one did. diff --git a/docs/frontend-system/utility-apis/05-migrating.md b/docs/frontend-system/utility-apis/05-migrating.md index b8cb50c224..f9590077ca 100644 --- a/docs/frontend-system/utility-apis/05-migrating.md +++ b/docs/frontend-system/utility-apis/05-migrating.md @@ -72,7 +72,7 @@ import { import { workApiRef } from '@internal/plugin-example-react'; import { WorkImpl } from './WorkImpl'; -const workApi = createApiFactory({ +const exampleWorkApi = createApiFactory({ api: workApiRef, deps: { storageApi: storageApiRef }, factory: ({ storageApi }) => new WorkImpl({ storageApi }), @@ -81,7 +81,7 @@ const workApi = createApiFactory({ /** @public */ export const catalogPlugin = createPlugin({ id: 'example', - apis: [workApi], + apis: [exampleWorkApi], }); ``` @@ -92,6 +92,8 @@ The major changes we'll make are - Change to the new version of `createPlugin` which exports this extension - Change the plugin export to be the default instead +The end result, after simplifying imports and cleaning up a bit, might look like this: + ```tsx title="in @internal/plugin-example" import { storageApiRef, @@ -102,7 +104,7 @@ import { import { workApiRef } from '@internal/plugin-example-react'; import { WorkImpl } from './WorkImpl'; -const workApi = createApiExtension({ +const exampleWorkApi = createApiExtension({ factory: createApiFactory({ api: workApiRef, deps: { storageApi: storageApiRef }, @@ -113,10 +115,10 @@ const workApi = createApiExtension({ /** @public */ export default createPlugin({ id: 'example', - extensions: [workApi], + extensions: [exampleWorkApi], }); ``` ## Further work -Since utility APIs are now complete extensions, you may want to take a bigger look at how they used to be used, and what the new frontend system offers. You may for example consider [adding configurability or inputs](./04-configuring.md) to your API, if that makes sense for your current application. +Since utility APIs are now complete extensions, you may want to take a bigger look at how they used to be used, and what the new frontend system offers. You may for example consider [adding configurability or inputs](./02-creating.md) to your API, if that makes sense for your current application. From 191f822d583351e926d01a3bc536701a43025882 Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Sun, 10 Dec 2023 13:59:01 -0600 Subject: [PATCH 234/275] Removed placeholder and moved text to description Signed-off-by: Andre Wanlin --- .github/ISSUE_TEMPLATE/bug.yaml | 21 +++++++-------------- .github/ISSUE_TEMPLATE/feature.yaml | 5 +---- .github/ISSUE_TEMPLATE/plugin.yaml | 5 +---- .github/ISSUE_TEMPLATE/rfc.yaml | 12 ++++-------- .github/ISSUE_TEMPLATE/ux_component.yaml | 13 +++++-------- 5 files changed, 18 insertions(+), 38 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug.yaml b/.github/ISSUE_TEMPLATE/bug.yaml index 57595621e4..356faa81ea 100644 --- a/.github/ISSUE_TEMPLATE/bug.yaml +++ b/.github/ISSUE_TEMPLATE/bug.yaml @@ -13,33 +13,29 @@ body: required: true attributes: label: '📜 Description' - description: 'A clear and concise description of what the bug is.' - placeholder: 'It bugs out when ...' + description: 'A clear and concise description of what the bug is. It bugs out when ...' - type: textarea id: expected-behavior validations: required: true attributes: label: '👍 Expected behavior' - description: 'What did you think should happen?' - placeholder: 'It should ...' + description: 'What did you think should happen? It should ...' - type: textarea id: actual-behavior validations: required: true attributes: label: '👎 Actual Behavior with Screenshots' - description: 'What did actually happen? Add screenshots, if applicable.' - placeholder: 'It actually ...' + description: 'What did actually happen? Add screenshots, if applicable. It actually ...' - type: textarea id: steps-to-reproduce validations: required: true attributes: label: '👟 Reproduction steps' - description: 'How do you trigger this bug? Please walk us through it step by step.' - placeholder: - "Provide a link to a live example, or an unambiguous set of steps to reproduce this bug. Include code or configuration to reproduce, if relevant.\n + description: 'How do you trigger this bug? Please walk us through it step by step. Provide a link to a live example, or an unambiguous set of steps to reproduce this bug. Include code or configuration to reproduce, if relevant.' + placeholder: "\n 1. Go to '...'\n 2. Click on '....'\n 3. Scroll down to '....'" @@ -49,17 +45,14 @@ body: required: false attributes: label: '📃 Provide the context for the Bug.' - description: 'How has this issue affected you? What are you trying to accomplish?' - placeholder: 'Providing context (e.g. links to configuration settings, stack trace or log data) helps us come up with a solution that is most useful in the real world.' + description: 'How has this issue affected you? What are you trying to accomplish? Providing context (e.g. links to configuration settings, stack trace or log data) helps us come up with a solution that is most useful in the real world.' - type: textarea id: environment validations: required: false attributes: label: '🖥️ Your Environment' - description: 'Provide Browser Information - Provide Output of `yarn backstage-cli info`' - placeholder: 'Include as many relevant details about the environment you experienced the bug in.' + description: 'Always provide output of `yarn backstage-cli info`; provide browser information when applicable. Include as many relevant details about the environment you experienced the bug in.' - type: checkboxes id: no-duplicate-issues attributes: diff --git a/.github/ISSUE_TEMPLATE/feature.yaml b/.github/ISSUE_TEMPLATE/feature.yaml index b2d5a6be81..8b1a697351 100644 --- a/.github/ISSUE_TEMPLATE/feature.yaml +++ b/.github/ISSUE_TEMPLATE/feature.yaml @@ -14,7 +14,6 @@ body: attributes: label: '🔖 Feature description' description: 'A clear and concise description of what the feature is.' - placeholder: 'You should add ...' - type: textarea id: context validations: @@ -22,13 +21,11 @@ body: attributes: label: '🎤 Context' description: 'Please explain why this feature should be implemented and how it would be used. Add examples, if applicable.' - placeholder: 'In my use-case, ...' - type: textarea id: implementation attributes: label: '✌️ Possible Implementation' - description: 'A clear and concise description of what you want to happen.' - placeholder: 'Not obligatory, but ideas as to the implementation of the addition or change' + description: 'A clear and concise description of what you want to happen. Not obligatory, but ideas as to the implementation of the addition or change.' - type: checkboxes id: no-duplicate-issues attributes: diff --git a/.github/ISSUE_TEMPLATE/plugin.yaml b/.github/ISSUE_TEMPLATE/plugin.yaml index a7f5216631..f77076146c 100644 --- a/.github/ISSUE_TEMPLATE/plugin.yaml +++ b/.github/ISSUE_TEMPLATE/plugin.yaml @@ -14,19 +14,16 @@ body: attributes: label: '🔖 Summary' description: 'Provide a general summary of the plugin and how it should work' - placeholder: 'You should add ...' - type: textarea id: website attributes: label: '🌐 Project website (if applicable)' description: 'Add a link to the open source project or product this plugin will integrate with, if existing' - placeholder: 'Website Link is ...' - type: textarea id: context attributes: label: '✌️ Context' - description: 'A clear and concise description about the Plugin.' - placeholder: 'Providing additional context' + description: 'A clear and concise description about the Plugin and any additional context.' - type: checkboxes id: no-duplicate-issues attributes: diff --git a/.github/ISSUE_TEMPLATE/rfc.yaml b/.github/ISSUE_TEMPLATE/rfc.yaml index 8e73992dc8..eae85419e7 100644 --- a/.github/ISSUE_TEMPLATE/rfc.yaml +++ b/.github/ISSUE_TEMPLATE/rfc.yaml @@ -13,28 +13,24 @@ body: required: true attributes: label: '🔖 Need' - description: 'Let us know why are you proposing this change' - placeholder: 'The problem we’re trying to address and the benefits/impact we expect to get from this are ...' + description: "Let us know why are you proposing this change. The problem we're trying to address and the benefits/impact we expect to get from this are ..." - type: textarea id: proposal validations: required: true attributes: label: '🎉 Proposal' - description: 'Describe the proposal in as much detail as needed for reviewers to give concrete feedback.' - placeholder: 'Take special care in this section to describe any implications on data privacy or security.' + description: 'Describe the proposal in as much detail as needed for reviewers to give concrete feedback. Take special care in this section to describe any implications on data privacy or security.' - type: textarea id: alternatives attributes: label: '〽️ Alternatives' - description: 'What alternatives to the proposed solution were considered?' - placeholder: 'What criteria/data was used to discard these?' + description: 'What alternatives to the proposed solution were considered? What criteria/data was used to discard these?' - type: textarea id: risk attributes: label: '❌ Risks' - description: 'What other things happening could conflict or compete (for example for resources) with the proposal?' - placeholder: 'What risk are there and how do we plan to handle them?' + description: 'What other things happening could conflict or compete (for example for resources) with the proposal? What risk are there and how do we plan to handle them?' - type: checkboxes id: no-duplicate-issues attributes: diff --git a/.github/ISSUE_TEMPLATE/ux_component.yaml b/.github/ISSUE_TEMPLATE/ux_component.yaml index c528356eb3..97280b67bf 100644 --- a/.github/ISSUE_TEMPLATE/ux_component.yaml +++ b/.github/ISSUE_TEMPLATE/ux_component.yaml @@ -6,37 +6,34 @@ body: - type: markdown attributes: value: | - We value your time and efforts to submit this RFC form. 🙏 + We value your time and efforts to submit this UX Component form. 🙏 - type: textarea id: ux-general validations: required: true attributes: label: '🔖 General' - description: 'Write a nice note to the community requesting the creation of a new component.' - placeholder: 'Include an image of your component. Bonus points for a GIF!' + description: | + 'Write a nice note to the community requesting the creation of a new component. Include an image of your component. Bonus points for a GIF!' - type: textarea id: usage validations: required: true attributes: label: '💻 Usage' - description: "Tell us what's the point of this component/pattern is." - placeholder: 'How does it help? How should it work? Any rules?' + description: "Tell us what's the point of this component/pattern is. How does it help? How should it work? Any rules?" - type: textarea id: specs validations: required: true attributes: label: '📐 Specs' - description: 'Include images that detail the redlines for your component.' - placeholder: "Once we get our Figma workspace set up, we'll be posting the Figma files rather than doing specs by hand." + description: "Include images that detail the redlines for your component. Once we get our Figma workspace set up, we'll be posting the Figma files rather than doing specs by hand." - type: textarea id: future attributes: label: '🔮 Future' description: 'List out any upcoming, exciting functionality for this component.' - placeholder: 'The component will have ...' - type: checkboxes id: no-duplicate-issues attributes: From b7de76ae7247e1f4ae36c9b4e0142e6c9d699d00 Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Thu, 23 Nov 2023 12:26:24 -0600 Subject: [PATCH 235/275] Introduced version policy for PostgreSQL Signed-off-by: Andre Wanlin Added changeset Signed-off-by: Andre Wanlin Updated API Report Signed-off-by: Andre Wanlin Updated references to use 12 and 16 Signed-off-by: Andre Wanlin Attempt to fix tests Signed-off-by: Andre Wanlin Added back old Ids Signed-off-by: Andre Wanlin Fixed test Signed-off-by: Andre Wanlin Updated API Report and test Signed-off-by: Andre Wanlin Added new setDefaults static method and related changes Signed-off-by: Andre Wanlin Updated API Report Signed-off-by: Andre Wanlin Improved logic based on feedback Signed-off-by: Andre Wanlin Added missing changeset Signed-off-by: Andre Wanlin Changes based on feedback Signed-off-by: Andre Wanlin API Report correction Signed-off-by: Andre Wanlin Updated to use new setDefaults Signed-off-by: Andre Wanlin --- .changeset/metal-countries-sniff.md | 5 ++ .changeset/witty-ears-repair.md | 7 +++ .github/uffizzi/k8s/manifests/pg-deploy.yaml | 2 +- .github/workflows/ci.yml | 12 ++-- .github/workflows/deploy_packages.yml | 12 ++-- .github/workflows/verify_e2e-linux.yml | 2 +- .../02-testing.md | 2 +- docs/overview/versioning-policy.md | 8 +++ packages/backend-tasks/src/migrations.test.ts | 4 +- packages/backend-tasks/src/setupTests.ts | 5 ++ .../src/tasks/PluginTaskSchedulerImpl.test.ts | 2 +- .../tasks/PluginTaskSchedulerJanitor.test.ts | 4 +- .../src/tasks/TaskScheduler.test.ts | 4 +- .../src/tasks/TaskWorker.test.ts | 4 +- packages/backend-test-utils/api-report.md | 4 ++ .../src/database/TestDatabases.test.ts | 62 +++++++++++++++++++ .../src/database/TestDatabases.ts | 26 +++++--- .../backend-test-utils/src/database/types.ts | 16 +++++ .../src/lib/assets/StaticAssetsStore.test.ts | 2 +- .../src/identity/DatabaseKeyStore.test.ts | 4 +- plugins/auth-backend/src/migrations.test.ts | 4 +- plugins/auth-backend/src/setupTests.ts | 6 ++ .../src/service/DatabaseHandler.test.ts | 2 +- .../src/module/WrapperProviders.test.ts | 2 +- .../database/DefaultCatalogDatabase.test.ts | 4 +- .../DefaultProcessingDatabase.test.ts | 4 +- .../database/DefaultProviderDatabase.test.ts | 4 +- .../deleteWithEagerPruningOfChildren.test.ts | 4 +- .../getDeferredStitchableEntities.test.ts | 4 +- .../markDeferredStitchCompleted.test.ts | 4 +- .../stitcher/markForStitching.test.ts | 4 +- .../stitcher/performStitching.test.ts | 4 +- .../util/deleteOrphanedEntities.test.ts | 4 +- .../modules/core/DefaultLocationStore.test.ts | 4 +- .../service/DefaultEntitiesCatalog.test.ts | 4 +- .../src/service/DefaultRefreshService.test.ts | 4 +- plugins/catalog-backend/src/setupTests.ts | 6 ++ .../src/stitching/DefaultStitcher.test.ts | 4 +- .../src/tests/migrations.test.ts | 4 +- .../performance/stitchingPerformance.test.ts | 2 +- .../src/database/util.test.ts | 2 +- .../service/fact/FactRetrieverEngine.test.ts | 2 +- .../vault-backend/src/service/router.test.ts | 2 +- .../src/service/standaloneApplication.ts | 2 +- 44 files changed, 180 insertions(+), 93 deletions(-) create mode 100644 .changeset/metal-countries-sniff.md create mode 100644 .changeset/witty-ears-repair.md diff --git a/.changeset/metal-countries-sniff.md b/.changeset/metal-countries-sniff.md new file mode 100644 index 0000000000..bef0a7209a --- /dev/null +++ b/.changeset/metal-countries-sniff.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-vault-backend': patch +--- + +Updated to test using PostgreSQL 12 and 16 diff --git a/.changeset/witty-ears-repair.md b/.changeset/witty-ears-repair.md new file mode 100644 index 0000000000..cdd4f3f271 --- /dev/null +++ b/.changeset/witty-ears-repair.md @@ -0,0 +1,7 @@ +--- +'@backstage/backend-test-utils': patch +--- + +Added support for PostgreSQL versions 15 and 16 + +Also introduced a new `setDefaults(options: { ids?: TestDatabaseId[] })` static method that can be added to the `setupTests.ts` file to define the default database ids you want to use throughout your package. Usage would look like this: `TestDatabases.setDefaults({ ids: ['POSTGRES_12','POSTGRES_16'] })` and would result in PostgreSQL versions 12 and 16 being used for your tests. diff --git a/.github/uffizzi/k8s/manifests/pg-deploy.yaml b/.github/uffizzi/k8s/manifests/pg-deploy.yaml index b842328978..950e64283f 100644 --- a/.github/uffizzi/k8s/manifests/pg-deploy.yaml +++ b/.github/uffizzi/k8s/manifests/pg-deploy.yaml @@ -15,7 +15,7 @@ spec: spec: containers: - name: postgres - image: postgres:13.2-alpine + image: postgres:12-alpine imagePullPolicy: 'IfNotPresent' ports: - containerPort: 5432 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 33d89b9c96..88faadaa68 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -153,8 +153,8 @@ jobs: name: Test ${{ matrix.node-version }} services: - postgres13: - image: postgres:13 + postgres16: + image: postgres:16 env: POSTGRES_PASSWORD: postgres options: >- @@ -164,8 +164,8 @@ jobs: --health-retries 5 ports: - 5432/tcp - postgres9: - image: postgres:9 + postgres12: + image: postgres:12 env: POSTGRES_PASSWORD: postgres options: >- @@ -218,8 +218,8 @@ jobs: run: yarn backstage-cli repo test --maxWorkers=2 --workerIdleMemoryLimit=1300M --since origin/master env: BACKSTAGE_TEST_DISABLE_DOCKER: 1 - BACKSTAGE_TEST_DATABASE_POSTGRES13_CONNECTION_STRING: postgresql://postgres:postgres@localhost:${{ job.services.postgres13.ports[5432] }} - BACKSTAGE_TEST_DATABASE_POSTGRES9_CONNECTION_STRING: postgresql://postgres:postgres@localhost:${{ job.services.postgres9.ports[5432] }} + BACKSTAGE_TEST_DATABASE_POSTGRES16_CONNECTION_STRING: postgresql://postgres:postgres@localhost:${{ job.services.postgres16.ports[5432] }} + BACKSTAGE_TEST_DATABASE_POSTGRES12_CONNECTION_STRING: postgresql://postgres:postgres@localhost:${{ job.services.postgres12.ports[5432] }} BACKSTAGE_TEST_DATABASE_MYSQL8_CONNECTION_STRING: mysql://root:root@localhost:${{ job.services.mysql8.ports[3306] }}/ignored # We run the test cases before verifying the specs to prevent any failing tests from causing errors. diff --git a/.github/workflows/deploy_packages.yml b/.github/workflows/deploy_packages.yml index 72124aa363..f6ad4d9742 100644 --- a/.github/workflows/deploy_packages.yml +++ b/.github/workflows/deploy_packages.yml @@ -17,8 +17,8 @@ jobs: node-version: [18.x, 20.x] services: - postgres13: - image: postgres:13 + postgres16: + image: postgres:16 env: POSTGRES_PASSWORD: postgres options: >- @@ -28,8 +28,8 @@ jobs: --health-retries 5 ports: - 5432/tcp - postgres9: - image: postgres:9 + postgres12: + image: postgres:12 env: POSTGRES_PASSWORD: postgres options: >- @@ -106,8 +106,8 @@ jobs: bash <(curl -s https://codecov.io/bash) -f packages/core-plugin-api/coverage/* -F core-plugin-api env: BACKSTAGE_TEST_DISABLE_DOCKER: 1 - BACKSTAGE_TEST_DATABASE_POSTGRES13_CONNECTION_STRING: postgresql://postgres:postgres@localhost:${{ job.services.postgres13.ports[5432] }} - BACKSTAGE_TEST_DATABASE_POSTGRES9_CONNECTION_STRING: postgresql://postgres:postgres@localhost:${{ job.services.postgres9.ports[5432] }} + BACKSTAGE_TEST_DATABASE_POSTGRES16_CONNECTION_STRING: postgresql://postgres:postgres@localhost:${{ job.services.postgres16.ports[5432] }} + BACKSTAGE_TEST_DATABASE_POSTGRES12_CONNECTION_STRING: postgresql://postgres:postgres@localhost:${{ job.services.postgres12.ports[5432] }} BACKSTAGE_TEST_DATABASE_MYSQL8_CONNECTION_STRING: mysql://root:root@localhost:${{ job.services.mysql8.ports[3306] }}/ignored - name: Discord notification diff --git a/.github/workflows/verify_e2e-linux.yml b/.github/workflows/verify_e2e-linux.yml index 89da89889f..e86608fcfe 100644 --- a/.github/workflows/verify_e2e-linux.yml +++ b/.github/workflows/verify_e2e-linux.yml @@ -18,7 +18,7 @@ jobs: services: postgres: - image: postgres:latest + image: postgres:12 env: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres diff --git a/docs/backend-system/building-plugins-and-modules/02-testing.md b/docs/backend-system/building-plugins-and-modules/02-testing.md index d14f7de09c..4bab1d1b9b 100644 --- a/docs/backend-system/building-plugins-and-modules/02-testing.md +++ b/docs/backend-system/building-plugins-and-modules/02-testing.md @@ -120,7 +120,7 @@ describe('MyDatabaseClass', () => { // "physical" databases to test against is much costlier than creating the // "logical" databases within them that the individual tests use. const databases = TestDatabases.create({ - ids: ['POSTGRES_13', 'POSTGRES_9', 'SQLITE_3', 'MYSQL_8'], + ids: ['POSTGRES_16', 'POSTGRES_12', 'SQLITE_3', 'MYSQL_8'], }); // Just an example of how to conveniently bundle up the setup code diff --git a/docs/overview/versioning-policy.md b/docs/overview/versioning-policy.md index c38ba404b5..8a23251ebb 100644 --- a/docs/overview/versioning-policy.md +++ b/docs/overview/versioning-policy.md @@ -182,3 +182,11 @@ The TypeScript release cadence is roughly every three months. An important aspec Our policy is to support the last 3 TypeScript versions, for example 4.8, 4.9, and 5.0. Converted to time, this means that we typically support the TypeScript version from the last six to nine months, depending on where in the TypeScript release window we are. This policy applies as a snapshot at the time of any given Backstage release, new TypeScript releases only apply to the following Backstage main-line release, not to the current one. For anyone maintaining their own Backstage project, this means that you should strive to bump to the latest TypeScript version at least every 6 months, or you may encounter breakages as you upgrade Backstage packages. If you encounter any issues in doing so, please [file an issue in the main Backstage repository](https://github.com/backstage/backstage/issues/new/choose), as per this policy we should always support the latest version. In order to ensure that we do not start using new TypeScript features too early, the Backstage project itself uses the version at the beginning of the currently supported window, in the above example that would be version 4.8. + +## PostgreSQL Releases + +The Backstage project recommends and supports using PostgreSQL for persistent storage. + +The PostgreSQL [versioning policy](https://www.postgresql.org/support/versioning/) is to release a new major version every year with new features which is then supported for 5 years after its initial release. + +Our policy mirrors the PostgreSQL versioning policy - we will support the last 5 major versions. We will also test the newest and oldest versions in that range. For example, if the range we support is currently 12 to 16, then we would only test 12 and 16 explicitly. diff --git a/packages/backend-tasks/src/migrations.test.ts b/packages/backend-tasks/src/migrations.test.ts index 1d701c971d..82208da975 100644 --- a/packages/backend-tasks/src/migrations.test.ts +++ b/packages/backend-tasks/src/migrations.test.ts @@ -42,9 +42,7 @@ async function migrateUntilBefore(knex: Knex, target: string): Promise { jest.setTimeout(60_000); describe('migrations', () => { - const databases = TestDatabases.create({ - ids: ['POSTGRES_13', 'POSTGRES_9', 'MYSQL_8', 'SQLITE_3'], - }); + const databases = TestDatabases.create(); it.each(databases.eachSupportedId())( '20210928160613_init.js, %p', diff --git a/packages/backend-tasks/src/setupTests.ts b/packages/backend-tasks/src/setupTests.ts index 5245d37c26..76619a2542 100644 --- a/packages/backend-tasks/src/setupTests.ts +++ b/packages/backend-tasks/src/setupTests.ts @@ -14,7 +14,12 @@ * limitations under the License. */ +import { TestDatabases } from '@backstage/backend-test-utils'; import { Settings } from 'luxon'; // TS still thinks that methods can return null / placeholders, but we still want to throw as soon as possible when things go wrong Settings.throwOnInvalid = true; + +TestDatabases.setDefaults({ + ids: ['MYSQL_8', 'POSTGRES_16', 'POSTGRES_12', 'SQLITE_3'], +}); diff --git a/packages/backend-tasks/src/tasks/PluginTaskSchedulerImpl.test.ts b/packages/backend-tasks/src/tasks/PluginTaskSchedulerImpl.test.ts index 6247755bbd..4b40791cb5 100644 --- a/packages/backend-tasks/src/tasks/PluginTaskSchedulerImpl.test.ts +++ b/packages/backend-tasks/src/tasks/PluginTaskSchedulerImpl.test.ts @@ -36,7 +36,7 @@ jest.setTimeout(60_000); describe('PluginTaskManagerImpl', () => { const databases = TestDatabases.create({ - ids: ['POSTGRES_13', 'POSTGRES_9', 'SQLITE_3'], + ids: ['POSTGRES_16', 'POSTGRES_12', 'SQLITE_3'], }); beforeAll(async () => { diff --git a/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.test.ts b/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.test.ts index 50bea27d27..1f0363625e 100644 --- a/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.test.ts +++ b/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.test.ts @@ -40,8 +40,8 @@ describe('PluginTaskSchedulerJanitor', () => { const databases = TestDatabases.create({ ids: [ /* 'MYSQL_8' not supported yet */ - 'POSTGRES_13', - 'POSTGRES_9', + 'POSTGRES_16', + 'POSTGRES_12', 'SQLITE_3', 'MYSQL_8', ], diff --git a/packages/backend-tasks/src/tasks/TaskScheduler.test.ts b/packages/backend-tasks/src/tasks/TaskScheduler.test.ts index 8e419437bc..d286eaee38 100644 --- a/packages/backend-tasks/src/tasks/TaskScheduler.test.ts +++ b/packages/backend-tasks/src/tasks/TaskScheduler.test.ts @@ -25,9 +25,7 @@ jest.setTimeout(60_000); describe('TaskScheduler', () => { const logger = getVoidLogger(); - const databases = TestDatabases.create({ - ids: ['POSTGRES_13', 'POSTGRES_9', 'SQLITE_3', 'MYSQL_8'], - }); + const databases = TestDatabases.create(); const testScopedSignal = createTestScopedSignal(); async function createDatabase( diff --git a/packages/backend-tasks/src/tasks/TaskWorker.test.ts b/packages/backend-tasks/src/tasks/TaskWorker.test.ts index 45eb7d1003..a2ecdaa779 100644 --- a/packages/backend-tasks/src/tasks/TaskWorker.test.ts +++ b/packages/backend-tasks/src/tasks/TaskWorker.test.ts @@ -28,9 +28,7 @@ jest.setTimeout(60_000); describe('TaskWorker', () => { const logger = getVoidLogger(); - const databases = TestDatabases.create({ - ids: ['POSTGRES_13', 'POSTGRES_9', 'SQLITE_3', 'MYSQL_8'], - }); + const databases = TestDatabases.create(); const testScopedSignal = createTestScopedSignal(); beforeEach(() => { diff --git a/packages/backend-test-utils/api-report.md b/packages/backend-test-utils/api-report.md index ac012e2f69..204e5dc84a 100644 --- a/packages/backend-test-utils/api-report.md +++ b/packages/backend-test-utils/api-report.md @@ -307,6 +307,8 @@ export interface TestBackendOptions { // @public export type TestDatabaseId = + | 'POSTGRES_16' + | 'POSTGRES_15' | 'POSTGRES_14' | 'POSTGRES_13' | 'POSTGRES_12' @@ -325,6 +327,8 @@ export class TestDatabases { eachSupportedId(): [TestDatabaseId][]; init(id: TestDatabaseId): Promise; // (undocumented) + static setDefaults(options: { ids?: TestDatabaseId[] }): void; + // (undocumented) supports(id: TestDatabaseId): boolean; } ``` diff --git a/packages/backend-test-utils/src/database/TestDatabases.test.ts b/packages/backend-test-utils/src/database/TestDatabases.test.ts index d766d38815..64e4d76443 100644 --- a/packages/backend-test-utils/src/database/TestDatabases.test.ts +++ b/packages/backend-test-utils/src/database/TestDatabases.test.ts @@ -59,6 +59,68 @@ describe('TestDatabases', () => { describe('each connect', () => { const dbs = TestDatabases.create(); + itIfDocker( + 'obeys a provided connection string for postgres 16', + async () => { + const { host, port, user, password, stop } = + await startPostgresContainer('postgres:16'); + + try { + // Leave a mark + process.env.BACKSTAGE_TEST_DATABASE_POSTGRES16_CONNECTION_STRING = `postgresql://${user}:${password}@${host}:${port}`; + const input = await dbs.init('POSTGRES_16'); + await input.schema.createTable('a', table => + table.string('x').primary(), + ); + await input.insert({ x: 'y' }).into('a'); + + // Look for the mark + const database = input.client.config.connection.database; + const output = knexFactory({ + client: 'pg', + connection: { host, port, user, password, database }, + }); + // eslint-disable-next-line jest/no-standalone-expect + await expect(output.select('x').from('a')).resolves.toEqual([ + { x: 'y' }, + ]); + } finally { + await stop(); + } + }, + ); + + itIfDocker( + 'obeys a provided connection string for postgres 15', + async () => { + const { host, port, user, password, stop } = + await startPostgresContainer('postgres:15'); + + try { + // Leave a mark + process.env.BACKSTAGE_TEST_DATABASE_POSTGRES15_CONNECTION_STRING = `postgresql://${user}:${password}@${host}:${port}`; + const input = await dbs.init('POSTGRES_15'); + await input.schema.createTable('a', table => + table.string('x').primary(), + ); + await input.insert({ x: 'y' }).into('a'); + + // Look for the mark + const database = input.client.config.connection.database; + const output = knexFactory({ + client: 'pg', + connection: { host, port, user, password, database }, + }); + // eslint-disable-next-line jest/no-standalone-expect + await expect(output.select('x').from('a')).resolves.toEqual([ + { x: 'y' }, + ]); + } finally { + await stop(); + } + }, + ); + itIfDocker( 'obeys a provided connection string for postgres 14', async () => { diff --git a/packages/backend-test-utils/src/database/TestDatabases.ts b/packages/backend-test-utils/src/database/TestDatabases.ts index 45d2899dbb..1913075b1f 100644 --- a/packages/backend-test-utils/src/database/TestDatabases.ts +++ b/packages/backend-test-utils/src/database/TestDatabases.ts @@ -44,6 +44,7 @@ const LARGER_POOL_CONFIG = { export class TestDatabases { private readonly instanceById: Map; private readonly supportedIds: TestDatabaseId[]; + private static defaultIds?: TestDatabaseId[]; /** * Creates an empty `TestDatabases` instance, and sets up Jest to clean up @@ -60,18 +61,19 @@ export class TestDatabases { ids?: TestDatabaseId[]; disableDocker?: boolean; }): TestDatabases { - const defaultOptions = { - ids: Object.keys(allDatabases) as TestDatabaseId[], - disableDocker: isDockerDisabledForTests(), - }; + const ids = options?.ids; + const disableDocker = options?.disableDocker ?? isDockerDisabledForTests(); - const { ids, disableDocker } = Object.assign( - {}, - defaultOptions, - options ?? {}, - ); + let testDatabaseIds: TestDatabaseId[]; + if (ids) { + testDatabaseIds = ids; + } else if (TestDatabases.defaultIds) { + testDatabaseIds = TestDatabases.defaultIds; + } else { + testDatabaseIds = Object.keys(allDatabases) as TestDatabaseId[]; + } - const supportedIds = ids.filter(id => { + const supportedIds = testDatabaseIds.filter(id => { const properties = allDatabases[id]; if (!properties) { return false; @@ -107,6 +109,10 @@ export class TestDatabases { return databases; } + static setDefaults(options: { ids?: TestDatabaseId[] }) { + TestDatabases.defaultIds = options.ids; + } + private constructor(supportedIds: TestDatabaseId[]) { this.instanceById = new Map(); this.supportedIds = supportedIds; diff --git a/packages/backend-test-utils/src/database/types.ts b/packages/backend-test-utils/src/database/types.ts index a7bfdeb12d..75c24dc725 100644 --- a/packages/backend-test-utils/src/database/types.ts +++ b/packages/backend-test-utils/src/database/types.ts @@ -24,6 +24,8 @@ import { getDockerImageForName } from '../util/getDockerImageForName'; * @public */ export type TestDatabaseId = + | 'POSTGRES_16' + | 'POSTGRES_15' | 'POSTGRES_14' | 'POSTGRES_13' | 'POSTGRES_12' @@ -47,6 +49,20 @@ export type Instance = { export const allDatabases: Record = Object.freeze({ + POSTGRES_16: { + name: 'Postgres 16.x', + driver: 'pg', + dockerImageName: getDockerImageForName('postgres:16'), + connectionStringEnvironmentVariableName: + 'BACKSTAGE_TEST_DATABASE_POSTGRES16_CONNECTION_STRING', + }, + POSTGRES_15: { + name: 'Postgres 15.x', + driver: 'pg', + dockerImageName: getDockerImageForName('postgres:15'), + connectionStringEnvironmentVariableName: + 'BACKSTAGE_TEST_DATABASE_POSTGRES15_CONNECTION_STRING', + }, POSTGRES_14: { name: 'Postgres 14.x', driver: 'pg', diff --git a/plugins/app-backend/src/lib/assets/StaticAssetsStore.test.ts b/plugins/app-backend/src/lib/assets/StaticAssetsStore.test.ts index f14349a55b..e18d136b9d 100644 --- a/plugins/app-backend/src/lib/assets/StaticAssetsStore.test.ts +++ b/plugins/app-backend/src/lib/assets/StaticAssetsStore.test.ts @@ -37,7 +37,7 @@ jest.setTimeout(60_000); describe('StaticAssetsStore', () => { const databases = TestDatabases.create({ - ids: ['MYSQL_8', 'POSTGRES_13', 'POSTGRES_9', 'SQLITE_3'], + ids: ['MYSQL_8', 'POSTGRES_16', 'POSTGRES_12', 'SQLITE_3'], }); it.each(databases.eachSupportedId())( diff --git a/plugins/auth-backend/src/identity/DatabaseKeyStore.test.ts b/plugins/auth-backend/src/identity/DatabaseKeyStore.test.ts index cf415c7e13..f86c4a400b 100644 --- a/plugins/auth-backend/src/identity/DatabaseKeyStore.test.ts +++ b/plugins/auth-backend/src/identity/DatabaseKeyStore.test.ts @@ -28,9 +28,7 @@ const keyBase = { jest.setTimeout(60_000); describe('DatabaseKeyStore', () => { - const databases = TestDatabases.create({ - ids: ['MYSQL_8', 'POSTGRES_13', 'POSTGRES_9', 'SQLITE_3'], - }); + const databases = TestDatabases.create(); it.each(databases.eachSupportedId())( 'should store a key, %p', diff --git a/plugins/auth-backend/src/migrations.test.ts b/plugins/auth-backend/src/migrations.test.ts index 194bbbf44c..f80b729975 100644 --- a/plugins/auth-backend/src/migrations.test.ts +++ b/plugins/auth-backend/src/migrations.test.ts @@ -42,9 +42,7 @@ async function migrateUntilBefore(knex: Knex, target: string): Promise { jest.setTimeout(60_000); describe('migrations', () => { - const databases = TestDatabases.create({ - ids: ['MYSQL_8', 'POSTGRES_13', 'POSTGRES_9', 'SQLITE_3'], - }); + const databases = TestDatabases.create(); it.each(databases.eachSupportedId())( '20230428155633_sessions.js, %p', diff --git a/plugins/auth-backend/src/setupTests.ts b/plugins/auth-backend/src/setupTests.ts index d3232290a7..f7c56ef27d 100644 --- a/plugins/auth-backend/src/setupTests.ts +++ b/plugins/auth-backend/src/setupTests.ts @@ -14,4 +14,10 @@ * limitations under the License. */ +import { TestDatabases } from '@backstage/backend-test-utils'; + export {}; + +TestDatabases.setDefaults({ + ids: ['MYSQL_8', 'POSTGRES_16', 'POSTGRES_12', 'SQLITE_3'], +}); diff --git a/plugins/bazaar-backend/src/service/DatabaseHandler.test.ts b/plugins/bazaar-backend/src/service/DatabaseHandler.test.ts index 4e46581240..39fa01ed3f 100644 --- a/plugins/bazaar-backend/src/service/DatabaseHandler.test.ts +++ b/plugins/bazaar-backend/src/service/DatabaseHandler.test.ts @@ -36,7 +36,7 @@ jest.setTimeout(60_000); describe('DatabaseHandler', () => { const databases = TestDatabases.create({ - ids: ['POSTGRES_13', 'POSTGRES_9', 'SQLITE_3', 'MYSQL_8'], + ids: ['POSTGRES_16', 'POSTGRES_12', 'SQLITE_3', 'MYSQL_8'], }); function createDatabaseManager( diff --git a/plugins/catalog-backend-module-incremental-ingestion/src/module/WrapperProviders.test.ts b/plugins/catalog-backend-module-incremental-ingestion/src/module/WrapperProviders.test.ts index 7d138e4812..9416fa27eb 100644 --- a/plugins/catalog-backend-module-incremental-ingestion/src/module/WrapperProviders.test.ts +++ b/plugins/catalog-backend-module-incremental-ingestion/src/module/WrapperProviders.test.ts @@ -26,7 +26,7 @@ jest.setTimeout(60_000); describe('WrapperProviders', () => { const applyDatabaseMigrations = jest.fn(); const databases = TestDatabases.create({ - ids: ['POSTGRES_13', 'POSTGRES_9', 'SQLITE_3', 'MYSQL_8'], + ids: ['POSTGRES_16', 'POSTGRES_12', 'SQLITE_3', 'MYSQL_8'], }); const config = new ConfigReader({}); const logger = getVoidLogger(); diff --git a/plugins/catalog-backend/src/database/DefaultCatalogDatabase.test.ts b/plugins/catalog-backend/src/database/DefaultCatalogDatabase.test.ts index bcc20816a4..ebcdc77287 100644 --- a/plugins/catalog-backend/src/database/DefaultCatalogDatabase.test.ts +++ b/plugins/catalog-backend/src/database/DefaultCatalogDatabase.test.ts @@ -25,9 +25,7 @@ jest.setTimeout(60_000); describe('DefaultCatalogDatabase', () => { const defaultLogger = getVoidLogger(); - const databases = TestDatabases.create({ - ids: ['MYSQL_8', 'POSTGRES_13', 'POSTGRES_9', 'SQLITE_3'], - }); + const databases = TestDatabases.create(); async function createDatabase( databaseId: TestDatabaseId, diff --git a/plugins/catalog-backend/src/database/DefaultProcessingDatabase.test.ts b/plugins/catalog-backend/src/database/DefaultProcessingDatabase.test.ts index db5153a8ba..080958da9b 100644 --- a/plugins/catalog-backend/src/database/DefaultProcessingDatabase.test.ts +++ b/plugins/catalog-backend/src/database/DefaultProcessingDatabase.test.ts @@ -37,9 +37,7 @@ jest.setTimeout(60_000); describe('DefaultProcessingDatabase', () => { const defaultLogger = getVoidLogger(); - const databases = TestDatabases.create({ - ids: ['MYSQL_8', 'POSTGRES_13', 'POSTGRES_9', 'SQLITE_3'], - }); + const databases = TestDatabases.create(); async function createDatabase( databaseId: TestDatabaseId, diff --git a/plugins/catalog-backend/src/database/DefaultProviderDatabase.test.ts b/plugins/catalog-backend/src/database/DefaultProviderDatabase.test.ts index 19093b542b..0d124b6d33 100644 --- a/plugins/catalog-backend/src/database/DefaultProviderDatabase.test.ts +++ b/plugins/catalog-backend/src/database/DefaultProviderDatabase.test.ts @@ -28,9 +28,7 @@ jest.setTimeout(60_000); describe('DefaultProviderDatabase', () => { const defaultLogger = getVoidLogger(); - const databases = TestDatabases.create({ - ids: ['MYSQL_8', 'POSTGRES_13', 'POSTGRES_9', 'SQLITE_3'], - }); + const databases = TestDatabases.create(); async function createDatabase( databaseId: TestDatabaseId, diff --git a/plugins/catalog-backend/src/database/operations/provider/deleteWithEagerPruningOfChildren.test.ts b/plugins/catalog-backend/src/database/operations/provider/deleteWithEagerPruningOfChildren.test.ts index 830cc20480..451f7bc1ac 100644 --- a/plugins/catalog-backend/src/database/operations/provider/deleteWithEagerPruningOfChildren.test.ts +++ b/plugins/catalog-backend/src/database/operations/provider/deleteWithEagerPruningOfChildren.test.ts @@ -28,9 +28,7 @@ import { deleteWithEagerPruningOfChildren } from './deleteWithEagerPruningOfChil jest.setTimeout(60_000); describe('deleteWithEagerPruningOfChildren', () => { - const databases = TestDatabases.create({ - ids: ['MYSQL_8', 'POSTGRES_13', 'POSTGRES_9', 'SQLITE_3'], - }); + const databases = TestDatabases.create(); async function createDatabase(databaseId: TestDatabaseId) { const knex = await databases.init(databaseId); diff --git a/plugins/catalog-backend/src/database/operations/stitcher/getDeferredStitchableEntities.test.ts b/plugins/catalog-backend/src/database/operations/stitcher/getDeferredStitchableEntities.test.ts index a909515f14..b66dc74ef2 100644 --- a/plugins/catalog-backend/src/database/operations/stitcher/getDeferredStitchableEntities.test.ts +++ b/plugins/catalog-backend/src/database/operations/stitcher/getDeferredStitchableEntities.test.ts @@ -21,9 +21,7 @@ import { getDeferredStitchableEntities } from './getDeferredStitchableEntities'; jest.setTimeout(60_000); describe('getDeferredStitchableEntities', () => { - const databases = TestDatabases.create({ - ids: ['MYSQL_8', 'POSTGRES_13', 'POSTGRES_9', 'SQLITE_3'], - }); + const databases = TestDatabases.create(); it.each(databases.eachSupportedId())( 'selects the right rows %p', diff --git a/plugins/catalog-backend/src/database/operations/stitcher/markDeferredStitchCompleted.test.ts b/plugins/catalog-backend/src/database/operations/stitcher/markDeferredStitchCompleted.test.ts index 76a6169cf4..b0957e0ec9 100644 --- a/plugins/catalog-backend/src/database/operations/stitcher/markDeferredStitchCompleted.test.ts +++ b/plugins/catalog-backend/src/database/operations/stitcher/markDeferredStitchCompleted.test.ts @@ -22,9 +22,7 @@ import { DbRefreshStateRow } from '../../tables'; jest.setTimeout(60_000); describe('markDeferredStitchCompleted', () => { - const databases = TestDatabases.create({ - ids: ['MYSQL_8', 'POSTGRES_13', 'POSTGRES_9', 'SQLITE_3'], - }); + const databases = TestDatabases.create(); it.each(databases.eachSupportedId())( 'completes only if unchanged %p', diff --git a/plugins/catalog-backend/src/database/operations/stitcher/markForStitching.test.ts b/plugins/catalog-backend/src/database/operations/stitcher/markForStitching.test.ts index 2cae76040b..011fe54e83 100644 --- a/plugins/catalog-backend/src/database/operations/stitcher/markForStitching.test.ts +++ b/plugins/catalog-backend/src/database/operations/stitcher/markForStitching.test.ts @@ -22,9 +22,7 @@ import { DbFinalEntitiesRow, DbRefreshStateRow } from '../../tables'; jest.setTimeout(60_000); describe('markForStitching', () => { - const databases = TestDatabases.create({ - ids: ['MYSQL_8', 'POSTGRES_13', 'POSTGRES_9', 'SQLITE_3'], - }); + const databases = TestDatabases.create(); it.each(databases.eachSupportedId())( 'marks the right rows in deferred mode %p', diff --git a/plugins/catalog-backend/src/database/operations/stitcher/performStitching.test.ts b/plugins/catalog-backend/src/database/operations/stitcher/performStitching.test.ts index a471f1dce2..e43424b361 100644 --- a/plugins/catalog-backend/src/database/operations/stitcher/performStitching.test.ts +++ b/plugins/catalog-backend/src/database/operations/stitcher/performStitching.test.ts @@ -30,9 +30,7 @@ import { performStitching } from './performStitching'; jest.setTimeout(60_000); describe('performStitching', () => { - const databases = TestDatabases.create({ - ids: ['MYSQL_8', 'POSTGRES_13', 'POSTGRES_9', 'SQLITE_3'], - }); + const databases = TestDatabases.create(); const logger = getVoidLogger(); // NOTE(freben): Testing the deferred path since it's a superset of the immediate one diff --git a/plugins/catalog-backend/src/database/operations/util/deleteOrphanedEntities.test.ts b/plugins/catalog-backend/src/database/operations/util/deleteOrphanedEntities.test.ts index 3dacc8f09b..1dc8a42d5f 100644 --- a/plugins/catalog-backend/src/database/operations/util/deleteOrphanedEntities.test.ts +++ b/plugins/catalog-backend/src/database/operations/util/deleteOrphanedEntities.test.ts @@ -29,9 +29,7 @@ import { deleteOrphanedEntities } from './deleteOrphanedEntities'; jest.setTimeout(60_000); describe('deleteOrphanedEntities', () => { - const databases = TestDatabases.create({ - ids: ['MYSQL_8', 'POSTGRES_13', 'POSTGRES_9', 'SQLITE_3'], - }); + const databases = TestDatabases.create(); async function createDatabase(databaseId: TestDatabaseId) { const knex = await databases.init(databaseId); diff --git a/plugins/catalog-backend/src/modules/core/DefaultLocationStore.test.ts b/plugins/catalog-backend/src/modules/core/DefaultLocationStore.test.ts index fca7faacf8..61eef2b8e5 100644 --- a/plugins/catalog-backend/src/modules/core/DefaultLocationStore.test.ts +++ b/plugins/catalog-backend/src/modules/core/DefaultLocationStore.test.ts @@ -22,9 +22,7 @@ import { DefaultLocationStore } from './DefaultLocationStore'; jest.setTimeout(60_000); describe('DefaultLocationStore', () => { - const databases = TestDatabases.create({ - ids: ['MYSQL_8', 'POSTGRES_13', 'POSTGRES_9', 'SQLITE_3'], - }); + const databases = TestDatabases.create(); async function createLocationStore(databaseId: TestDatabaseId) { const knex = await databases.init(databaseId); diff --git a/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.test.ts b/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.test.ts index fde3408c4b..fe7d57c89a 100644 --- a/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.test.ts +++ b/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.test.ts @@ -44,9 +44,7 @@ describe('DefaultEntitiesCatalog', () => { await knex.destroy(); }); - const databases = TestDatabases.create({ - ids: ['MYSQL_8', 'POSTGRES_13', 'POSTGRES_9', 'SQLITE_3'], - }); + const databases = TestDatabases.create(); const stitch = jest.fn(); const stitcher: Stitcher = { stitch } as any; diff --git a/plugins/catalog-backend/src/service/DefaultRefreshService.test.ts b/plugins/catalog-backend/src/service/DefaultRefreshService.test.ts index 5b29bb34d5..e1b775cce6 100644 --- a/plugins/catalog-backend/src/service/DefaultRefreshService.test.ts +++ b/plugins/catalog-backend/src/service/DefaultRefreshService.test.ts @@ -39,9 +39,7 @@ jest.setTimeout(60_000); describe('DefaultRefreshService', () => { const defaultLogger = getVoidLogger(); - const databases = TestDatabases.create({ - ids: ['MYSQL_8', 'POSTGRES_13', 'POSTGRES_9', 'SQLITE_3'], - }); + const databases = TestDatabases.create(); async function createDatabase( databaseId: TestDatabaseId, diff --git a/plugins/catalog-backend/src/setupTests.ts b/plugins/catalog-backend/src/setupTests.ts index d3232290a7..f7c56ef27d 100644 --- a/plugins/catalog-backend/src/setupTests.ts +++ b/plugins/catalog-backend/src/setupTests.ts @@ -14,4 +14,10 @@ * limitations under the License. */ +import { TestDatabases } from '@backstage/backend-test-utils'; + export {}; + +TestDatabases.setDefaults({ + ids: ['MYSQL_8', 'POSTGRES_16', 'POSTGRES_12', 'SQLITE_3'], +}); diff --git a/plugins/catalog-backend/src/stitching/DefaultStitcher.test.ts b/plugins/catalog-backend/src/stitching/DefaultStitcher.test.ts index 5b33fc424c..5e7ba7ef71 100644 --- a/plugins/catalog-backend/src/stitching/DefaultStitcher.test.ts +++ b/plugins/catalog-backend/src/stitching/DefaultStitcher.test.ts @@ -30,9 +30,7 @@ import { DefaultStitcher } from './DefaultStitcher'; jest.setTimeout(60_000); describe('Stitcher', () => { - const databases = TestDatabases.create({ - ids: ['MYSQL_8', 'POSTGRES_13', 'POSTGRES_9', 'SQLITE_3'], - }); + const databases = TestDatabases.create(); const logger = getVoidLogger(); it.each(databases.eachSupportedId())( diff --git a/plugins/catalog-backend/src/tests/migrations.test.ts b/plugins/catalog-backend/src/tests/migrations.test.ts index aa305598aa..d961427f5e 100644 --- a/plugins/catalog-backend/src/tests/migrations.test.ts +++ b/plugins/catalog-backend/src/tests/migrations.test.ts @@ -42,9 +42,7 @@ async function migrateUntilBefore(knex: Knex, target: string): Promise { jest.setTimeout(60_000); describe('migrations', () => { - const databases = TestDatabases.create({ - ids: ['MYSQL_8', 'POSTGRES_13', 'POSTGRES_9', 'SQLITE_3'], - }); + const databases = TestDatabases.create(); it.each(databases.eachSupportedId())( 'latest version correctly cascades deletions, %p', diff --git a/plugins/catalog-backend/src/tests/performance/stitchingPerformance.test.ts b/plugins/catalog-backend/src/tests/performance/stitchingPerformance.test.ts index 7902a5e230..e0d3f87124 100644 --- a/plugins/catalog-backend/src/tests/performance/stitchingPerformance.test.ts +++ b/plugins/catalog-backend/src/tests/performance/stitchingPerformance.test.ts @@ -155,7 +155,7 @@ class Tracker { describePerformanceTest('stitchingPerformance', () => { const databases = TestDatabases.create({ - ids: [/* 'MYSQL_8', */ 'POSTGRES_13', 'POSTGRES_9', 'SQLITE_3'], + ids: [/* 'MYSQL_8', */ 'POSTGRES_16', 'POSTGRES_12', 'SQLITE_3'], }); it.each(databases.eachSupportedId())( diff --git a/plugins/search-backend-module-pg/src/database/util.test.ts b/plugins/search-backend-module-pg/src/database/util.test.ts index 781805b3a3..38d997c836 100644 --- a/plugins/search-backend-module-pg/src/database/util.test.ts +++ b/plugins/search-backend-module-pg/src/database/util.test.ts @@ -38,7 +38,7 @@ describe('util', () => { describe('supported', () => { const databases = TestDatabases.create({ - ids: ['POSTGRES_13', 'POSTGRES_9'], + ids: ['POSTGRES_16', 'POSTGRES_12'], }); if (databases.eachSupportedId().length < 1) { diff --git a/plugins/tech-insights-backend/src/service/fact/FactRetrieverEngine.test.ts b/plugins/tech-insights-backend/src/service/fact/FactRetrieverEngine.test.ts index 5473b28c62..677b778b9b 100644 --- a/plugins/tech-insights-backend/src/service/fact/FactRetrieverEngine.test.ts +++ b/plugins/tech-insights-backend/src/service/fact/FactRetrieverEngine.test.ts @@ -117,7 +117,7 @@ describe('FactRetrieverEngine', () => { } const databases = TestDatabases.create({ - ids: ['POSTGRES_13', 'POSTGRES_9', 'SQLITE_3'], + ids: ['POSTGRES_16', 'POSTGRES_12', 'SQLITE_3'], }); async function createEngine( diff --git a/plugins/vault-backend/src/service/router.test.ts b/plugins/vault-backend/src/service/router.test.ts index 97997b30ef..3fb78a6e8d 100644 --- a/plugins/vault-backend/src/service/router.test.ts +++ b/plugins/vault-backend/src/service/router.test.ts @@ -26,7 +26,7 @@ import { createRouter } from './router'; describe('createRouter', () => { let app: express.Express; const databases = TestDatabases.create({ - ids: ['POSTGRES_13', 'POSTGRES_9', 'SQLITE_3'], + ids: ['POSTGRES_16', 'POSTGRES_12', 'SQLITE_3'], }); beforeAll(async () => { diff --git a/plugins/vault-backend/src/service/standaloneApplication.ts b/plugins/vault-backend/src/service/standaloneApplication.ts index ba4c0edc3e..c0a011c61c 100644 --- a/plugins/vault-backend/src/service/standaloneApplication.ts +++ b/plugins/vault-backend/src/service/standaloneApplication.ts @@ -48,7 +48,7 @@ export async function createStandaloneApplication( const app = express(); const databases = TestDatabases.create({ - ids: ['POSTGRES_13', 'POSTGRES_9', 'SQLITE_3'], + ids: ['POSTGRES_16', 'POSTGRES_12', 'SQLITE_3'], }); const knex = await databases.init('SQLITE_3'); const databaseManager: Partial = { From 89987680236e08a133d421038be4a2ddc6abb8dc Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Fri, 15 Dec 2023 14:56:02 -0600 Subject: [PATCH 236/275] Updated all the Dicebear usages to the proper API URL Signed-off-by: Andre Wanlin --- .../examples/acme/backstage-group.yaml | 4 +++- packages/catalog-model/examples/acme/org.yaml | 2 +- .../examples/acme/team-a-group.yaml | 9 ++++----- .../examples/acme/team-b-group.yaml | 12 ++++++------ .../examples/acme/team-c-group.yaml | 12 ++++++------ .../examples/acme/team-d-group.yaml | 6 +++--- plugins/org/src/__testUtils__/catalogMocks.ts | 18 ++++++------------ .../GroupProfile/GroupProfileCard.stories.tsx | 6 +++--- .../MembersList/MembersListCard.stories.tsx | 4 ++-- .../OwnershipCard/OwnershipCard.stories.tsx | 2 +- .../UserProfileCard.stories.tsx | 4 ---- 11 files changed, 35 insertions(+), 44 deletions(-) diff --git a/packages/catalog-model/examples/acme/backstage-group.yaml b/packages/catalog-model/examples/acme/backstage-group.yaml index f83587532c..f04830e475 100644 --- a/packages/catalog-model/examples/acme/backstage-group.yaml +++ b/packages/catalog-model/examples/acme/backstage-group.yaml @@ -8,6 +8,8 @@ spec: profile: displayName: Backstage email: backstage@example.com - picture: https://avatars.dicebear.com/api/identicon/backstage@example.com.svg?background=%23fff&margin=25 + picture: https://api.dicebear.com/7.x/identicon/svg?seed=Fluffy&backgroundColor=ffdfbf parent: infrastructure children: [team-a, team-b] + + diff --git a/packages/catalog-model/examples/acme/org.yaml b/packages/catalog-model/examples/acme/org.yaml index 9a0d690b57..96dd3a4e9e 100644 --- a/packages/catalog-model/examples/acme/org.yaml +++ b/packages/catalog-model/examples/acme/org.yaml @@ -13,7 +13,7 @@ spec: profile: displayName: ACME Corp email: info@example.com - picture: https://avatars.dicebear.com/api/identicon/info@example.com.svg?background=%23fff&margin=25 + picture: https://api.dicebear.com/7.x/identicon/svg?seed=Maggie&flip=true&backgroundColor=ffdfbf children: [infrastructure] --- apiVersion: backstage.io/v1alpha1 diff --git a/packages/catalog-model/examples/acme/team-a-group.yaml b/packages/catalog-model/examples/acme/team-a-group.yaml index e343209d5f..7fe0e7b3f3 100644 --- a/packages/catalog-model/examples/acme/team-a-group.yaml +++ b/packages/catalog-model/examples/acme/team-a-group.yaml @@ -8,7 +8,7 @@ spec: profile: # Intentional no displayName for testing email: team-a@example.com - picture: https://avatars.dicebear.com/api/identicon/team-a@example.com.svg?background=%23fff&margin=25 + picture: https://api.dicebear.com/7.x/identicon/svg?seed=Fluffy&backgroundType=solid,gradientLinear&backgroundColor=ffd5dc,b6e3f4 parent: backstage children: [] --- @@ -20,7 +20,7 @@ spec: profile: # Intentional no displayName for testing email: breanna-davison@example.com - picture: https://avatars.dicebear.com/api/avataaars/breanna-davison@example.com.svg?background=%23fff + picture: https://api.dicebear.com/7.x/avataaars/svg?seed=Luna&backgroundColor=transparent memberOf: [team-a] --- apiVersion: backstage.io/v1alpha1 @@ -31,7 +31,7 @@ spec: profile: displayName: Janelle Dawe email: janelle-dawe@example.com - picture: https://avatars.dicebear.com/api/avataaars/janelle-dawe@example.com.svg?background=%23fff + picture: https://api.dicebear.com/7.x/avataaars/svg?seed=Leo&backgroundColor=transparent memberOf: [team-a] --- apiVersion: backstage.io/v1alpha1 @@ -42,7 +42,7 @@ spec: profile: displayName: Nigel Manning email: nigel-manning@example.com - picture: https://avatars.dicebear.com/api/avataaars/nigel-manning@example.com.svg?background=%23fff + picture: https://api.dicebear.com/7.x/avataaars/svg?seed=Midnight&backgroundColor=transparent memberOf: [team-a] --- # This user is added as an example, to make it more easy for the "Guest" @@ -56,5 +56,4 @@ spec: profile: displayName: Guest User email: guest@example.com - picture: https://avatars.dicebear.com/api/avataaars/guest@example.com.svg?background=%23fff memberOf: [team-a] diff --git a/packages/catalog-model/examples/acme/team-b-group.yaml b/packages/catalog-model/examples/acme/team-b-group.yaml index 20ab8721ea..63dd000fb4 100644 --- a/packages/catalog-model/examples/acme/team-b-group.yaml +++ b/packages/catalog-model/examples/acme/team-b-group.yaml @@ -8,7 +8,7 @@ spec: profile: displayName: Team B email: team-b@example.com - picture: https://avatars.dicebear.com/api/identicon/team-b@example.com.svg?background=%23fff&margin=25 + picture: https://api.dicebear.com/7.x/identicon/svg?seed=Abby&backgroundType=solid,gradientLinear&backgroundColor=ffd5dc,b6e3f4 parent: backstage children: [] --- @@ -20,7 +20,7 @@ spec: profile: displayName: Amelia Park email: amelia-park@example.com - picture: https://avatars.dicebear.com/api/avataaars/amelia-park@example.com.svg?background=%23fff + picture: https://api.dicebear.com/7.x/avataaars/svg?seed=Gizmo&backgroundColor=transparent memberOf: [team-b] --- apiVersion: backstage.io/v1alpha1 @@ -31,7 +31,7 @@ spec: profile: displayName: Colette Brock email: colette-brock@example.com - picture: https://avatars.dicebear.com/api/avataaars/colette-brock@example.com.svg?background=%23fff + picture: https://api.dicebear.com/7.x/avataaars/svg?seed=Bailey&backgroundColor=transparent memberOf: [team-b] --- apiVersion: backstage.io/v1alpha1 @@ -42,7 +42,7 @@ spec: profile: displayName: Jenny Doe email: jenny-doe@example.com - picture: https://avatars.dicebear.com/api/avataaars/jenny-doe@example.com.svg?background=%23fff + picture: https://api.dicebear.com/7.x/avataaars/svg?seed=Mimi&backgroundColor=transparent memberOf: [team-b] --- apiVersion: backstage.io/v1alpha1 @@ -53,7 +53,7 @@ spec: profile: displayName: Jonathon Page email: jonathon-page@example.com - picture: https://avatars.dicebear.com/api/avataaars/jonathon-page@example.com.svg?background=%23fff + picture: https://api.dicebear.com/7.x/avataaars/svg?seed=Baby&backgroundColor=transparent memberOf: [team-b] --- apiVersion: backstage.io/v1alpha1 @@ -64,5 +64,5 @@ spec: profile: displayName: Justine Barrow email: justine-barrow@example.com - picture: https://avatars.dicebear.com/api/avataaars/justine-barrow@example.com.svg?background=%23fff + picture: https://api.dicebear.com/7.x/avataaars/svg?seed=Sassy&backgroundColor=transparent memberOf: [team-b] diff --git a/packages/catalog-model/examples/acme/team-c-group.yaml b/packages/catalog-model/examples/acme/team-c-group.yaml index 639b591d61..2daaa1daba 100644 --- a/packages/catalog-model/examples/acme/team-c-group.yaml +++ b/packages/catalog-model/examples/acme/team-c-group.yaml @@ -8,7 +8,7 @@ spec: profile: displayName: Team C email: team-c@example.com - picture: https://avatars.dicebear.com/api/identicon/team-c@example.com.svg?background=%23fff&margin=25 + picture: https://api.dicebear.com/7.x/identicon/svg?seed=Loki&backgroundType=gradientLinear&backgroundColor=b6e3f4,ffd5dc,ffdfbf,c0aede parent: boxoffice children: [] --- @@ -20,7 +20,7 @@ spec: profile: displayName: Calum Leavy email: calum-leavy@example.com - picture: https://avatars.dicebear.com/api/avataaars/calum-leavy@example.com.svg?background=%23fff + picture: https://api.dicebear.com/7.x/avataaars/svg?seed=Bear&backgroundColor=transparent memberOf: [team-c] --- apiVersion: backstage.io/v1alpha1 @@ -31,7 +31,7 @@ spec: profile: displayName: Frank Tiernan email: frank-tiernan@example.com - picture: https://avatars.dicebear.com/api/avataaars/frank-tiernan@example.com.svg?background=%23fff + picture: https://api.dicebear.com/7.x/avataaars/svg?seed=Bandit&backgroundColor=transparent memberOf: [team-c] --- apiVersion: backstage.io/v1alpha1 @@ -42,7 +42,7 @@ spec: profile: displayName: Peadar MacMahon email: peadar-macmahon@example.com - picture: https://avatars.dicebear.com/api/avataaars/peadar-macmahon@example.com.svg?background=%23fff + picture: https://api.dicebear.com/7.x/avataaars/svg?seed=Sophie memberOf: [team-c] --- apiVersion: backstage.io/v1alpha1 @@ -53,7 +53,7 @@ spec: profile: displayName: Sarah Gilroy email: sarah-gilroy@example.com - picture: https://avatars.dicebear.com/api/avataaars/sarah-gilroy@example.com.svg?background=%23fff + picture: https://api.dicebear.com/7.x/avataaars/svg?seed=Rascal memberOf: [team-c] --- apiVersion: backstage.io/v1alpha1 @@ -64,5 +64,5 @@ spec: profile: displayName: Tara MacGovern email: tara-macgovern@example.com - picture: https://avatars.dicebear.com/api/avataaars/tara-macgovern@example.com.svg?background=%23fff + picture: https://api.dicebear.com/7.x/avataaars/svg?seed=Jasmine memberOf: [team-c] diff --git a/packages/catalog-model/examples/acme/team-d-group.yaml b/packages/catalog-model/examples/acme/team-d-group.yaml index 898ed8be6c..ac6d70772e 100644 --- a/packages/catalog-model/examples/acme/team-d-group.yaml +++ b/packages/catalog-model/examples/acme/team-d-group.yaml @@ -8,7 +8,7 @@ spec: profile: displayName: Team D email: team-d@example.com - picture: https://avatars.dicebear.com/api/identicon/team-d@example.com.svg?background=%23fff&margin=25 + picture: https://api.dicebear.com/7.x/identicon/svg?seed=Bailey&backgroundType=gradientLinear&backgroundColor=b6e3f4,ffd5dc,ffdfbf,c0aede parent: boxoffice children: [] --- @@ -20,7 +20,7 @@ spec: profile: displayName: Eva MacDowell email: eva-macdowell@example.com - picture: https://avatars.dicebear.com/api/avataaars/eva-macdowell@example.com.svg?background=%23fff + picture: https://api.dicebear.com/7.x/avataaars/svg?seed=Cuddles memberOf: [team-d] --- apiVersion: backstage.io/v1alpha1 @@ -31,5 +31,5 @@ spec: profile: displayName: Lucy Sheehan email: lucy-sheehan@example.com - picture: https://avatars.dicebear.com/api/avataaars/lucy-sheehan@example.com.svg?background=%23fff + picture: https://api.dicebear.com/7.x/avataaars/svg?seed=Snickers memberOf: [team-d] diff --git a/plugins/org/src/__testUtils__/catalogMocks.ts b/plugins/org/src/__testUtils__/catalogMocks.ts index b14856e345..a97caa9971 100644 --- a/plugins/org/src/__testUtils__/catalogMocks.ts +++ b/plugins/org/src/__testUtils__/catalogMocks.ts @@ -208,8 +208,7 @@ export const groupAUserOne: Entity = { profile: { displayName: 'Group A User One', email: 'group-a-user-one@testing.email', - picture: - 'https://avatars.dicebear.com/api/avataaars/breanna-davison@example.com.svg', + picture: 'https://api.dicebear.com/7.x/avataaars/svg?seed=Buster', }, }, }; @@ -224,8 +223,7 @@ export const groupBUserOne: Entity = { profile: { displayName: 'Group B User One', email: 'group-b-user-one@testing.email', - picture: - 'https://avatars.dicebear.com/api/avataaars/breanna-davison@example.com.svg', + picture: 'https://api.dicebear.com/7.x/avataaars/svg?seed=Buster', }, }, }; @@ -240,8 +238,7 @@ export const groupDUserOne: Entity = { profile: { displayName: 'Group D User One', email: 'group-d-user-one@testing.email', - picture: - 'https://avatars.dicebear.com/api/avataaars/breanna-davison@example.com.svg', + picture: 'https://api.dicebear.com/7.x/avataaars/svg?seed=Buster', }, }, }; @@ -256,8 +253,7 @@ export const groupEUserOne: Entity = { profile: { displayName: 'Group E User One', email: 'group-e-user-one@testing.email', - picture: - 'https://avatars.dicebear.com/api/avataaars/breanna-davison@example.com.svg', + picture: 'https://api.dicebear.com/7.x/avataaars/svg?seed=Buster', }, }, }; @@ -272,8 +268,7 @@ export const groupFUserOne: Entity = { profile: { displayName: 'Group F User One', email: 'group-f-user-one@testing.email', - picture: - 'https://avatars.dicebear.com/api/avataaars/breanna-davison@example.com.svg', + picture: 'https://api.dicebear.com/7.x/avataaars/svg?seed=Buster', }, }, }; @@ -288,8 +283,7 @@ export const duplicatedUser: Entity = { profile: { displayName: 'Duplicated User', email: 'duplicated-user@testing.email', - picture: - 'https://avatars.dicebear.com/api/avataaars/breanna-davison@example.com.svg', + picture: 'https://api.dicebear.com/7.x/avataaars/svg?seed=Buster', }, }, }; diff --git a/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.stories.tsx b/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.stories.tsx index e10d6322e0..62ecca14e0 100644 --- a/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.stories.tsx +++ b/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.stories.tsx @@ -48,7 +48,7 @@ const defaultEntity: GroupEntity = { displayName: 'Team A', email: 'team-a@example.com', picture: - 'https://avatars.dicebear.com/api/identicon/team-a@example.com.svg?background=%23fff&margin=25', + 'https://api.dicebear.com/7.x/identicon/svg?seed=Fluffy&backgroundType=solid,gradientLinear&backgroundColor=ffd5dc,b6e3f4', }, type: 'group', children: [], @@ -111,7 +111,7 @@ const extraDetailsEntity: GroupEntity = { displayName: 'Team A', email: 'team-a@example.com', picture: - 'https://avatars.dicebear.com/api/identicon/team-a@example.com.svg?background=%23fff&margin=25', + 'https://api.dicebear.com/7.x/identicon/svg?seed=Fluffy&backgroundType=solid,gradientLinear&backgroundColor=ffd5dc,b6e3f4', }, type: 'group', children: [], @@ -141,7 +141,7 @@ const groupWithTitle: GroupEntity = { profile: { email: 'team-a@example.com', picture: - 'https://avatars.dicebear.com/api/identicon/team-a@example.com.svg?background=%23fff&margin=25', + 'https://api.dicebear.com/7.x/identicon/svg?seed=Fluffy&backgroundType=solid,gradientLinear&backgroundColor=ffd5dc,b6e3f4', }, type: 'group', children: [], diff --git a/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.stories.tsx b/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.stories.tsx index 6b34d8b934..0e2b6a39f7 100644 --- a/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.stories.tsx +++ b/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.stories.tsx @@ -55,7 +55,7 @@ const makeUser = ({ profile: { displayName, email, - picture: `https://avatars.dicebear.com/api/avataaars/${email}.svg?background=%23fff`, + picture: `https://api.dicebear.com/7.x/avataaars/svg?seed=bob${name}`, }, }, relations: [ @@ -83,7 +83,7 @@ const defaultEntity: GroupEntity = { displayName: 'Team A', email: 'team-a@example.com', picture: - 'https://avatars.dicebear.com/api/identicon/team-a@example.com.svg?background=%23fff&margin=25', + 'https://api.dicebear.com/7.x/identicon/svg?seed=Fluffy&backgroundType=solid,gradientLinear&backgroundColor=ffd5dc,b6e3f4', }, type: 'group', children: [], diff --git a/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.stories.tsx b/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.stories.tsx index 390fff12a4..1f50dc33d8 100644 --- a/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.stories.tsx +++ b/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.stories.tsx @@ -44,7 +44,7 @@ const defaultEntity: GroupEntity = { displayName: 'Team A', email: 'team-a@example.com', picture: - 'https://avatars.dicebear.com/api/identicon/team-a@example.com.svg?background=%23fff&margin=25', + 'https://api.dicebear.com/7.x/identicon/svg?seed=Fluffy&backgroundType=solid,gradientLinear&backgroundColor=ffd5dc,b6e3f4', }, type: 'group', children: [], diff --git a/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.stories.tsx b/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.stories.tsx index 02598691e0..6326a043bc 100644 --- a/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.stories.tsx +++ b/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.stories.tsx @@ -45,8 +45,6 @@ const defaultEntity: UserEntity = { profile: { displayName: 'Guest User', email: 'guest@example.com', - picture: - 'https://avatars.dicebear.com/api/avataaars/guest@example.com.svg?background=%23fff', }, memberOf: ['team-a'], }, @@ -125,8 +123,6 @@ const extraDetailsEntity: UserEntity = { profile: { displayName: 'Guest User', email: 'guest@example.com', - picture: - 'https://avatars.dicebear.com/api/avataaars/guest@example.com.svg?background=%23fff', }, memberOf: ['team-a'], }, From d818220a5269dd3c477d7bfb29fd599a435b0b46 Mon Sep 17 00:00:00 2001 From: Armel Soro Date: Tue, 12 Dec 2023 00:56:08 +0100 Subject: [PATCH 237/275] Microsite: Add Scaffolder Devfile Selector Plugin Signed-off-by: Armel Soro --- .../plugins/scaffolder-frontend-devfile-field.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 microsite/data/plugins/scaffolder-frontend-devfile-field.yaml diff --git a/microsite/data/plugins/scaffolder-frontend-devfile-field.yaml b/microsite/data/plugins/scaffolder-frontend-devfile-field.yaml new file mode 100644 index 0000000000..3215c63795 --- /dev/null +++ b/microsite/data/plugins/scaffolder-frontend-devfile-field.yaml @@ -0,0 +1,10 @@ +--- +title: Devfile Selector Field Extension +author: Red Hat +authorUrl: https://developers.redhat.com +category: Scaffolder +description: Devfile Selector Field Extension to use in your Software Templates. Devfile is an open standard defining containerized development environments. +documentation: https://github.com/redhat-developer/backstage-odo-devfile-plugin/blob/main/packages/devfile-field-extension/README.md +iconUrl: https://landscape.cncf.io/logos/devfile.svg +npmPackageName: '@redhat-developer/plugin-scaffolder-frontend-module-devfile-field' +addedDate: '2023-12-08' From 5ce77dcdc4d413b0f5463d641c09f937094eac28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Mon, 18 Dec 2023 09:30:18 +0100 Subject: [PATCH 238/275] prettier MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- README-ko_kr.md | 3 ++- README.md | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README-ko_kr.md b/README-ko_kr.md index 42049f434b..f7bcba144b 100644 --- a/README-ko_kr.md +++ b/README-ko_kr.md @@ -1,7 +1,7 @@ [![headline](docs/assets/headline.png)](https://backstage.io/) - # [Backstage](https://backstage.io) + [English](README.md) \| 한국어 [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) @@ -23,6 +23,7 @@ Backstage 는 모든 인프라 도구, 서비스 및 문서를 통합하여 처 ![software-catalog](docs/assets/header.png) Backstage 다음을 포함합니다: + - [Backstage Software Catalog](https://backstage.io/docs/features/software-catalog/) 마이크로 서비스, 라이브러리, 데이터 파이프라인, 웹 사이트, ML 모델 등 모든 소프트웨어 관리 - [Backstage Software Templates](https://backstage.io/docs/features/software-templates/) 새로운 프로젝트를 신속하게 시작하고 조직의 모밤 사례에따라 도구를 표준화 - [Backstage TechDocs](https://backstage.io/docs/features/techdocs/) "docs like code" 접근 방식을 사용하여 기술 문서를 쉽게 작성, 유지 관리, 검색 및 사용 diff --git a/README.md b/README.md index 9f34c83dc1..9ddcfaa706 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ [![headline](docs/assets/headline.png)](https://backstage.io/) # [Backstage](https://backstage.io) + English \| [한국어](README-ko_kr.md) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) From 941f13e6ff66892f1773a70719140d5cc132b8ca Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Mon, 18 Dec 2023 12:19:18 +0100 Subject: [PATCH 239/275] docs(frontend-test-utils): improve changeset content Co-authored-by: Patrik Oldsberg Signed-off-by: Camila Belo --- .changeset/cool-fans-wash.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/cool-fans-wash.md b/.changeset/cool-fans-wash.md index 8154298047..07d38e7ea2 100644 --- a/.changeset/cool-fans-wash.md +++ b/.changeset/cool-fans-wash.md @@ -2,4 +2,4 @@ '@backstage/frontend-test-utils': patch --- -Accepts rendering more than a route in the test app. +The `createExtensionTester` helper is now able to render more than one route in the test app. From 88df7561be8ea891680b40e48e7a148b430a111b Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Mon, 18 Dec 2023 12:32:15 +0100 Subject: [PATCH 240/275] refactor(frontend-test-utils): remove components dependency Signed-off-by: Camila Belo --- packages/frontend-test-utils/package.json | 1 - .../src/app/createExtensionTester.test.tsx | 4 ++-- .../frontend-test-utils/src/app/createExtensionTester.tsx | 8 +++----- yarn.lock | 1 - 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/packages/frontend-test-utils/package.json b/packages/frontend-test-utils/package.json index 33b1f41a8c..7f157cdc4f 100644 --- a/packages/frontend-test-utils/package.json +++ b/packages/frontend-test-utils/package.json @@ -31,7 +31,6 @@ "dist" ], "dependencies": { - "@backstage/core-components": "workspace:^", "@backstage/frontend-app-api": "workspace:^", "@backstage/frontend-plugin-api": "workspace:^", "@backstage/test-utils": "workspace:^", diff --git a/packages/frontend-test-utils/src/app/createExtensionTester.test.tsx b/packages/frontend-test-utils/src/app/createExtensionTester.test.tsx index de52ca52de..04da2b7e89 100644 --- a/packages/frontend-test-utils/src/app/createExtensionTester.test.tsx +++ b/packages/frontend-test-utils/src/app/createExtensionTester.test.tsx @@ -15,6 +15,7 @@ */ import React, { useCallback } from 'react'; +import { Link } from 'react-router-dom'; import { fireEvent, screen, waitFor } from '@testing-library/react'; import { analyticsApiRef, @@ -27,7 +28,6 @@ import { useAnalytics, useApi, } from '@backstage/frontend-plugin-api'; -import { Link } from '@backstage/core-components'; import { MockAnalyticsApi } from '../apis'; import { createExtensionTester } from './createExtensionTester'; @@ -175,7 +175,7 @@ describe('createExtensionTester', () => { ).resolves.toBeInTheDocument(); }); - it('should capture click events in anylitics', async () => { + it('should capture click events in analytics', async () => { // Mocking the analytics api implementation const analyticsApiMock = new MockAnalyticsApi(); diff --git a/packages/frontend-test-utils/src/app/createExtensionTester.tsx b/packages/frontend-test-utils/src/app/createExtensionTester.tsx index 0404cf1ade..fdac4746d5 100644 --- a/packages/frontend-test-utils/src/app/createExtensionTester.tsx +++ b/packages/frontend-test-utils/src/app/createExtensionTester.tsx @@ -15,8 +15,7 @@ */ import React, { ComponentType, ReactNode, useContext, useState } from 'react'; -import { MemoryRouter } from 'react-router-dom'; -import { Link } from '@backstage/core-components'; +import { MemoryRouter, Link } from 'react-router-dom'; import { RenderResult, render } from '@testing-library/react'; import { createSpecializedApp } from '@backstage/frontend-app-api'; import { @@ -40,7 +39,7 @@ import { resolveExtensionDefinition } from '../../../frontend-plugin-api/src/wir // eslint-disable-next-line @backstage/no-relative-monorepo-imports import { createSignInPageExtension } from '../../../frontend-plugin-api/src/extensions/createSignInPageExtension'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { InternalExtensionDefinition } from '../../../frontend-plugin-api/src/wiring/createExtension'; +import { toInternalExtensionDefinition } from '../../../frontend-plugin-api/src/wiring/createExtension'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports import { InternalAppContext } from '../../../frontend-app-api/src/wiring/InternalAppContext'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports @@ -195,8 +194,7 @@ export class ExtensionTester { options?: { config?: TConfig }, ): ExtensionTester { const tester = new ExtensionTester(); - const { output, factory, ...rest } = - subject as InternalExtensionDefinition; + const { output, factory, ...rest } = toInternalExtensionDefinition(subject); // attaching to core/routes to render as index route const extension = createExtension({ ...rest, diff --git a/yarn.lock b/yarn.lock index 910432180d..aef0f13137 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4227,7 +4227,6 @@ __metadata: resolution: "@backstage/frontend-test-utils@workspace:packages/frontend-test-utils" dependencies: "@backstage/cli": "workspace:^" - "@backstage/core-components": "workspace:^" "@backstage/frontend-app-api": "workspace:^" "@backstage/frontend-plugin-api": "workspace:^" "@backstage/test-utils": "workspace:^" From cb4928f94b1d004f3d77d0611bcc7fe6076a2f2c Mon Sep 17 00:00:00 2001 From: npiyush97 Date: Mon, 18 Dec 2023 17:18:36 +0530 Subject: [PATCH 241/275] removed duplicate code Signed-off-by: npiyush97 --- .../src/actions/gitHelpers.ts | 9 --------- 1 file changed, 9 deletions(-) diff --git a/plugins/scaffolder-backend-module-github/src/actions/gitHelpers.ts b/plugins/scaffolder-backend-module-github/src/actions/gitHelpers.ts index f94cf1e71c..dc3313d589 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/gitHelpers.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/gitHelpers.ts @@ -129,15 +129,6 @@ export const enableBranchProtectionOnDefaultRepoBranch = async ({ } }; -export function getGitCommitMessage( - gitCommitMessage: string | undefined, - config: Config, -): string | undefined { - return gitCommitMessage - ? gitCommitMessage - : config.getOptionalString('scaffolder.defaultCommitMessage'); -} - export function entityRefToName(name: string): string { return name.replace(/^.*[:/]/g, ''); } From 9d82ee99f23dc3bfeb15fdd49453ac6a9a67a543 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Mon, 18 Dec 2023 12:43:51 +0100 Subject: [PATCH 242/275] refactor: apply testing docs suggestions Signed-off-by: Camila Belo --- .../building-plugins/testing.md | 90 +++++++++---------- 1 file changed, 44 insertions(+), 46 deletions(-) diff --git a/docs/frontend-system/building-plugins/testing.md b/docs/frontend-system/building-plugins/testing.md index c3315d2821..7fe719b1a3 100644 --- a/docs/frontend-system/building-plugins/testing.md +++ b/docs/frontend-system/building-plugins/testing.md @@ -14,7 +14,7 @@ description: Testing plugins in the frontend system Utilities for testing frontend features and components are available in `@backstage/frontend-test-utils`. -## Testing components +## Testing React components A component can be used for more than one extension, and it should be tested independently of an extension environment. @@ -28,7 +28,7 @@ import { EntityDetails } from './plugin'; describe('Entity details component', () => { it('should render the entity name and owner', async () => { - renderInTestApp(); + await renderInTestApp(); await expect( screen.getByText('The entity "test" is owned by "tools"'), @@ -37,7 +37,7 @@ describe('Entity details component', () => { }); ``` -It's important to highlight that mocking APIs for components is different from mocking them for extensions. In the snippet below, we wrapped the component within a `TestApiProvider` for mocking the Catalog API: +To mock [Utility APIs](../utility-apis/01-index.md) that are used by your component you can use the `TestApiProvider` to override individual API implementations. In the snippet below, we wrap the component within a `TestApiProvider` in order to mock the catalog client API: ```tsx import React from 'react'; @@ -52,14 +52,15 @@ import { EntityDetails } from './plugin'; describe('Entity details component', () => { it('should render the entity name and owner', async () => { - const catalogApiMock: Partial = { - getEntityFacets: () => - Promise.resolve({ + const catalogApiMock = { + async getEntityFacets() { + return { facets: { 'relations.ownedBy': [{ count: 1, value: 'group:default/tools' }], }, - }), - }; + }, + } + } satisfies Partial; const entityRef = stringifyEntityRef({ kind: 'Component', @@ -67,7 +68,7 @@ describe('Entity details component', () => { name: 'test', }); - renderInTestApp( + await renderInTestApp( , @@ -80,9 +81,9 @@ describe('Entity details component', () => { }); ``` -## Testing features +## Testing extensions -To facilitate testing of frontend features, the `@backstage/frontend-test-utils` package provides a tester class which starts up an entire frontend harness, complete with a number of default features. You can then provide overrides for extensions whose behavior you need to adjust for the test run. +To facilitate testing of frontend extensions, the `@backstage/frontend-test-utils` package provides a tester class which starts up an entire frontend harness, complete with a number of default features. You can then provide overrides for extensions whose behavior you need to adjust for the test run. A number of features (frontend extensions and overrides) are also accepted by the tester. Here are some examples of how these facilities can be useful: @@ -97,9 +98,7 @@ import { indexPageExtension } from './plugin'; describe('Index page', () => { it('should render a the index page', () => { - const tester = createExtensionTester(indexPageExtension); - - tester.render(); + createExtensionTester(indexPageExtension).render(); expect(screen.getByText('Index Page')).toBeInTheDocument(); }); @@ -118,17 +117,18 @@ import { indexPageExtension, detailsPageExtension } from './plugin'; describe('Index page', async () => { it('should link to the details page', () => { - const tester = createExtensionTester(indexPageExtension); + createExtensionTester(indexPageExtension) + // Adding more extensions to the preset being tested + .add(detailsPageExtension) + .render(); - // Adding more extensions to the preset being tested - tester.add(detailsPageExtension); - tester.render(); + await expect(screen.findByText('Index Page')).toBeInTheDocument(); - expect(screen.getByText('Index Page')).toBeInTheDocument(); + await userEvent.click(screen.getByRole('link', { name: 'See details' })); - userEvent.click(screen.getByRole('link', { name: 'See details' })); - - await expect(screen.getByText('Details Page')).resolves.toBeInTheDocument(); + await expect( + screen.findByText('Details Page'), + ).resolves.toBeInTheDocument(); }); }); ``` @@ -154,7 +154,7 @@ import { import { indexPageExtension } from './plugin'; describe('Index page', () => { - it('should capture click events in anylitics', async () => { + it('should capture click events in analytics', async () => { // Mocking the analytics api implementation const analyticsApiMock = new MockAnalyticsApi(); @@ -165,14 +165,14 @@ describe('Index page', () => { }), }); - const tester = createExtensionTester(indexPageExtension); + createExtensionTester(indexPageExtension) + // Overriding the analytics api extension + .add(analyticsApiOverride) + .render(); - // Overriding the analytics api extension - tester.add(analyticsApiOverride); - - tester.render(); - - userEvent.click(await screen.findByRole('link', { name: 'See details' })); + await userEvent.click( + await screen.findByRole('link', { name: 'See details' }), + ); expect(analyticsApiMock.getEvents()[0]).toMatchObject({ action: 'click', @@ -194,24 +194,22 @@ import { indexPageExtension, detailsPageExtension } from './plugin'; describe('Index page', () => { it('should accepts a custom title via config', async () => { - const tester = createExtensionTester(indexPageExtension, { + createExtensionTester(indexPageExtension, { // Configuration specific of index page config: { title: 'Custom index' }, - }); - - tester.add(detailsExtensionPage, { - // Configuration specific of details page - config: { title: 'Custom details' }, - }); - - tester.render({ - // Configuration specific of the instance - config: { - app: { - title: 'Custom app', + }) + .add(detailsExtensionPage, { + // Configuration specific of details page + config: { title: 'Custom details' }, + }) + .render({ + // Configuration specific of the instance + config: { + app: { + title: 'Custom app', + }, }, - }, - }); + }); await expect( screen.findByRole('heading', { name: 'Custom app' }), @@ -221,7 +219,7 @@ describe('Index page', () => { screen.findByRole('heading', { name: 'Custom index' }), ).resolves.toBeInTheDocument(); - userEvent.click(screen.getByRole('link', { name: 'See details' })); + await userEvent.click(screen.getByRole('link', { name: 'See details' })); await expect( screen.findByText('Custom details'), From b60b2455d2ade5ddea692a949b29d832e313d419 Mon Sep 17 00:00:00 2001 From: blam Date: Sat, 11 Nov 2023 13:47:38 +0100 Subject: [PATCH 243/275] chore: adding secret field extension Signed-off-by: blam Signed-off-by: blam --- .../src/components/fields/Secret/Secret.tsx | 50 +++++++++++++++++++ .../src/components/fields/Secret/index.tsx | 16 ++++++ .../scaffolder/src/components/fields/index.ts | 2 + plugins/scaffolder/src/extensions/default.ts | 5 ++ 4 files changed, 73 insertions(+) create mode 100644 plugins/scaffolder/src/components/fields/Secret/Secret.tsx create mode 100644 plugins/scaffolder/src/components/fields/Secret/index.tsx diff --git a/plugins/scaffolder/src/components/fields/Secret/Secret.tsx b/plugins/scaffolder/src/components/fields/Secret/Secret.tsx new file mode 100644 index 0000000000..bdd862f8ce --- /dev/null +++ b/plugins/scaffolder/src/components/fields/Secret/Secret.tsx @@ -0,0 +1,50 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { useTemplateSecrets } from '@backstage/plugin-scaffolder-react'; +import { ScaffolderRJSFFieldProps } from '@backstage/plugin-scaffolder-react'; +import { ScaffolderField } from '@backstage/plugin-scaffolder-react/alpha'; +import { Input, InputLabel } from '@material-ui/core'; + +export const Secret = (props: ScaffolderRJSFFieldProps) => { + const { setSecrets } = useTemplateSecrets(); + const { + name, + schema: { title, description }, + rawErrors, + disabled, + errors, + required, + } = props; + + return ( + + {title} + setSecrets({ [name]: e.target?.value })} + type="password" + /> + + ); +}; diff --git a/plugins/scaffolder/src/components/fields/Secret/index.tsx b/plugins/scaffolder/src/components/fields/Secret/index.tsx new file mode 100644 index 0000000000..e28248ef7d --- /dev/null +++ b/plugins/scaffolder/src/components/fields/Secret/index.tsx @@ -0,0 +1,16 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export * from './Secret'; diff --git a/plugins/scaffolder/src/components/fields/index.ts b/plugins/scaffolder/src/components/fields/index.ts index 7ee4448f6b..e29a4d791c 100644 --- a/plugins/scaffolder/src/components/fields/index.ts +++ b/plugins/scaffolder/src/components/fields/index.ts @@ -19,4 +19,6 @@ export * from './RepoUrlPicker'; export * from './OwnedEntityPicker'; export * from './EntityTagsPicker'; export * from './MyGroupsPicker'; +export * from './Secret'; + export { type FieldSchema, makeFieldSchemaFromZod } from './utils'; diff --git a/plugins/scaffolder/src/extensions/default.ts b/plugins/scaffolder/src/extensions/default.ts index 013f242a12..ef4a701e86 100644 --- a/plugins/scaffolder/src/extensions/default.ts +++ b/plugins/scaffolder/src/extensions/default.ts @@ -43,6 +43,7 @@ import { MyGroupsPicker, MyGroupsPickerSchema, } from '../components/fields/MyGroupsPicker/MyGroupsPicker'; +import { Secret } from '../components'; export const DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS = [ { @@ -82,4 +83,8 @@ export const DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS = [ name: 'MyGroupsPicker', schema: MyGroupsPickerSchema, }, + { + component: Secret, + name: 'Secret', + }, ]; From 77333b626d57c06d0ddf7a3c3e80f0e41273ffc3 Mon Sep 17 00:00:00 2001 From: blam Date: Sat, 11 Nov 2023 13:56:27 +0100 Subject: [PATCH 244/275] chore: added things Signed-off-by: blam --- plugins/scaffolder/src/components/fields/Secret/Secret.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/scaffolder/src/components/fields/Secret/Secret.tsx b/plugins/scaffolder/src/components/fields/Secret/Secret.tsx index bdd862f8ce..59256c5c09 100644 --- a/plugins/scaffolder/src/components/fields/Secret/Secret.tsx +++ b/plugins/scaffolder/src/components/fields/Secret/Secret.tsx @@ -41,9 +41,10 @@ export const Secret = (props: ScaffolderRJSFFieldProps) => { {title} setSecrets({ [name]: e.target?.value })} type="password" + autoComplete="off" /> ); From da34ebee34dd04b2e2b1ba64fee142550d1e1a20 Mon Sep 17 00:00:00 2001 From: blam Date: Mon, 13 Nov 2023 11:14:52 +0100 Subject: [PATCH 245/275] wip Signed-off-by: blam Signed-off-by: blam --- .../sample-templates/all-templates.yaml | 1 + .../sample-templates/template.yaml | 19 +++++++++++++ .../src/components/fields/Secret/index.tsx | 1 + .../components/fields/Secret/validation.ts | 27 +++++++++++++++++++ plugins/scaffolder/src/extensions/default.ts | 3 ++- 5 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 plugins/scaffolder-backend/sample-templates/template.yaml create mode 100644 plugins/scaffolder/src/components/fields/Secret/validation.ts diff --git a/plugins/scaffolder-backend/sample-templates/all-templates.yaml b/plugins/scaffolder-backend/sample-templates/all-templates.yaml index 6637c9479b..fb2db2e608 100644 --- a/plugins/scaffolder-backend/sample-templates/all-templates.yaml +++ b/plugins/scaffolder-backend/sample-templates/all-templates.yaml @@ -6,6 +6,7 @@ metadata: spec: targets: - ./remote-templates.yaml + - ./template.yaml # For local development of a template, you can reference your local templates here. # Examples: # diff --git a/plugins/scaffolder-backend/sample-templates/template.yaml b/plugins/scaffolder-backend/sample-templates/template.yaml new file mode 100644 index 0000000000..6aad96b2e7 --- /dev/null +++ b/plugins/scaffolder-backend/sample-templates/template.yaml @@ -0,0 +1,19 @@ +apiVersion: scaffolder.backstage.io/v1beta3 +kind: Template +metadata: + name: test + title: Test template +spec: + parameters: + - title: Do something + properties: + myKey: + title: My key + description: asd + type: string + ui:field: Secret + ui:options: + required: true + steps: [] + type: service + \ No newline at end of file diff --git a/plugins/scaffolder/src/components/fields/Secret/index.tsx b/plugins/scaffolder/src/components/fields/Secret/index.tsx index e28248ef7d..83d7576552 100644 --- a/plugins/scaffolder/src/components/fields/Secret/index.tsx +++ b/plugins/scaffolder/src/components/fields/Secret/index.tsx @@ -14,3 +14,4 @@ * limitations under the License. */ export * from './Secret'; +export * from './validation'; diff --git a/plugins/scaffolder/src/components/fields/Secret/validation.ts b/plugins/scaffolder/src/components/fields/Secret/validation.ts new file mode 100644 index 0000000000..e7cb6566e7 --- /dev/null +++ b/plugins/scaffolder/src/components/fields/Secret/validation.ts @@ -0,0 +1,27 @@ +import { CustomFieldValidator } from '@backstage/plugin-scaffolder-react'; + +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export const secretFieldValidation: CustomFieldValidator = ( + value, + errors, + { uiSchema }, +) => { + console.log(uiSchema); + if (uiSchema['ui:options'].required && !value) { + errors.addError('Required'); + } +}; diff --git a/plugins/scaffolder/src/extensions/default.ts b/plugins/scaffolder/src/extensions/default.ts index ef4a701e86..24b70b6a0c 100644 --- a/plugins/scaffolder/src/extensions/default.ts +++ b/plugins/scaffolder/src/extensions/default.ts @@ -43,7 +43,7 @@ import { MyGroupsPicker, MyGroupsPickerSchema, } from '../components/fields/MyGroupsPicker/MyGroupsPicker'; -import { Secret } from '../components'; +import { Secret, secretFieldValidation } from '../components'; export const DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS = [ { @@ -86,5 +86,6 @@ export const DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS = [ { component: Secret, name: 'Secret', + validation: secretFieldValidation, }, ]; From a7a5568788f54644d8298dafab068ac9f5e0f682 Mon Sep 17 00:00:00 2001 From: npiyush97 Date: Mon, 18 Dec 2023 17:58:36 +0530 Subject: [PATCH 246/275] refactor Signed-off-by: npiyush97 --- .../scaffolder-backend-module-github/src/actions/gitHelpers.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/scaffolder-backend-module-github/src/actions/gitHelpers.ts b/plugins/scaffolder-backend-module-github/src/actions/gitHelpers.ts index dc3313d589..84d8e507b3 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/gitHelpers.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/gitHelpers.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import { Config } from '@backstage/config'; import { assertError } from '@backstage/errors'; import { Octokit } from 'octokit'; import { Logger } from 'winston'; From 9bda7ea3d7c8152bf948c2b62e50a6085e4b77d4 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Mon, 18 Dec 2023 13:49:35 +0100 Subject: [PATCH 247/275] docs: fix link to utility apis Signed-off-by: Camila Belo --- docs/frontend-system/building-plugins/testing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/building-plugins/testing.md b/docs/frontend-system/building-plugins/testing.md index 7fe719b1a3..8177724ae1 100644 --- a/docs/frontend-system/building-plugins/testing.md +++ b/docs/frontend-system/building-plugins/testing.md @@ -37,7 +37,7 @@ describe('Entity details component', () => { }); ``` -To mock [Utility APIs](../utility-apis/01-index.md) that are used by your component you can use the `TestApiProvider` to override individual API implementations. In the snippet below, we wrap the component within a `TestApiProvider` in order to mock the catalog client API: +To mock [Utility APIs](../architecture/06-utility-apis.md) that are used by your component you can use the `TestApiProvider` to override individual API implementations. In the snippet below, we wrap the component within a `TestApiProvider` in order to mock the catalog client API: ```tsx import React from 'react'; From c22929665fa5a770e9ad4fc622ff341138562496 Mon Sep 17 00:00:00 2001 From: blam Date: Mon, 18 Dec 2023 13:56:15 +0100 Subject: [PATCH 248/275] chore: work around some of the secret validation Signed-off-by: blam --- .../sample-templates/template.yaml | 4 +-- .../src/components/fields/Secret/Secret.tsx | 14 +++++++++- .../src/components/fields/Secret/index.tsx | 1 - .../components/fields/Secret/validation.ts | 27 ------------------- plugins/scaffolder/src/extensions/default.ts | 3 +-- 5 files changed, 16 insertions(+), 33 deletions(-) delete mode 100644 plugins/scaffolder/src/components/fields/Secret/validation.ts diff --git a/plugins/scaffolder-backend/sample-templates/template.yaml b/plugins/scaffolder-backend/sample-templates/template.yaml index 6aad96b2e7..8d0ec0316f 100644 --- a/plugins/scaffolder-backend/sample-templates/template.yaml +++ b/plugins/scaffolder-backend/sample-templates/template.yaml @@ -6,14 +6,14 @@ metadata: spec: parameters: - title: Do something + required: + - myKey properties: myKey: title: My key description: asd type: string ui:field: Secret - ui:options: - required: true steps: [] type: service \ No newline at end of file diff --git a/plugins/scaffolder/src/components/fields/Secret/Secret.tsx b/plugins/scaffolder/src/components/fields/Secret/Secret.tsx index 59256c5c09..2933a405f1 100644 --- a/plugins/scaffolder/src/components/fields/Secret/Secret.tsx +++ b/plugins/scaffolder/src/components/fields/Secret/Secret.tsx @@ -27,6 +27,7 @@ export const Secret = (props: ScaffolderRJSFFieldProps) => { rawErrors, disabled, errors, + onChange, required, } = props; @@ -42,7 +43,18 @@ export const Secret = (props: ScaffolderRJSFFieldProps) => { setSecrets({ [name]: e.target?.value })} + onChange={e => { + // TODO(blam): this is a bit of a hack. We need to to probably figure out + // how to provide our own validator that can filter out the secrets from the + // jsonschema, or merge the secrets with the formData for validation? + // Makes the review step a little cleaner with this though. + onChange( + Array(e.target?.value.length ?? 0) + .fill('*') + .join(''), + ); + setSecrets({ [name]: e.target?.value }); + }} type="password" autoComplete="off" /> diff --git a/plugins/scaffolder/src/components/fields/Secret/index.tsx b/plugins/scaffolder/src/components/fields/Secret/index.tsx index 83d7576552..e28248ef7d 100644 --- a/plugins/scaffolder/src/components/fields/Secret/index.tsx +++ b/plugins/scaffolder/src/components/fields/Secret/index.tsx @@ -14,4 +14,3 @@ * limitations under the License. */ export * from './Secret'; -export * from './validation'; diff --git a/plugins/scaffolder/src/components/fields/Secret/validation.ts b/plugins/scaffolder/src/components/fields/Secret/validation.ts deleted file mode 100644 index e7cb6566e7..0000000000 --- a/plugins/scaffolder/src/components/fields/Secret/validation.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { CustomFieldValidator } from '@backstage/plugin-scaffolder-react'; - -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export const secretFieldValidation: CustomFieldValidator = ( - value, - errors, - { uiSchema }, -) => { - console.log(uiSchema); - if (uiSchema['ui:options'].required && !value) { - errors.addError('Required'); - } -}; diff --git a/plugins/scaffolder/src/extensions/default.ts b/plugins/scaffolder/src/extensions/default.ts index 24b70b6a0c..ef4a701e86 100644 --- a/plugins/scaffolder/src/extensions/default.ts +++ b/plugins/scaffolder/src/extensions/default.ts @@ -43,7 +43,7 @@ import { MyGroupsPicker, MyGroupsPickerSchema, } from '../components/fields/MyGroupsPicker/MyGroupsPicker'; -import { Secret, secretFieldValidation } from '../components'; +import { Secret } from '../components'; export const DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS = [ { @@ -86,6 +86,5 @@ export const DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS = [ { component: Secret, name: 'Secret', - validation: secretFieldValidation, }, ]; From 96cf824297e5b6a6a176e49512945ce5c117cefc Mon Sep 17 00:00:00 2001 From: blam Date: Mon, 18 Dec 2023 14:09:05 +0100 Subject: [PATCH 249/275] chore: added some test Signed-off-by: blam --- .../components/fields/Secret/Secret.test.tsx | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 plugins/scaffolder/src/components/fields/Secret/Secret.test.tsx diff --git a/plugins/scaffolder/src/components/fields/Secret/Secret.test.tsx b/plugins/scaffolder/src/components/fields/Secret/Secret.test.tsx new file mode 100644 index 0000000000..fd30c6afff --- /dev/null +++ b/plugins/scaffolder/src/components/fields/Secret/Secret.test.tsx @@ -0,0 +1,107 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { + SecretsContextProvider, + useTemplateSecrets, +} from '@backstage/plugin-scaffolder-react'; +import { Secret } from './Secret'; +import { renderInTestApp } from '@backstage/test-utils'; +import { Form } from '@backstage/plugin-scaffolder-react/alpha'; +import validator from '@rjsf/validator-ajv8'; +import { fireEvent, act } from '@testing-library/react'; + +describe('', () => { + const SecretsComponent = () => { + const { secrets } = useTemplateSecrets(); + return ( +
    {JSON.stringify({ secrets })}
    + ); + }; + + it('should set the current form value as a mask for the value entered', async () => { + const mockSecret = 'backstage'; + const onSubmit = jest.fn(); + + const { getByLabelText, getByRole } = await renderInTestApp( + +
    + + , + ); + + const secretInput = getByLabelText('secret'); + const submitButton = getByRole('button'); + + await act(async () => { + fireEvent.change(secretInput, { target: { value: mockSecret } }); + fireEvent.click(submitButton); + }); + + expect(onSubmit).toHaveBeenCalledWith( + expect.objectContaining({ + formData: '*********', + }), + expect.anything(), + ); + }); + + it('should set the secret value to the unmasked value', async () => { + const mockSecret = 'backstage'; + const onSubmit = jest.fn(); + + const { getByLabelText, getByTestId } = await renderInTestApp( + + + + , + ); + + const secretInput = getByLabelText('secret'); + + await act(async () => { + fireEvent.change(secretInput, { target: { value: mockSecret } }); + }); + + const { secrets } = JSON.parse(getByTestId('current-secrets').textContent!); + + expect(secrets.myKey).toBe(mockSecret); + }); +}); From 30f2066896929fb817687eb01ec57cfaa9fd2fcd Mon Sep 17 00:00:00 2001 From: blam Date: Mon, 18 Dec 2023 14:18:07 +0100 Subject: [PATCH 250/275] chore: added documentation and deprecating old method Signed-off-by: blam --- .../software-templates/writing-templates.md | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/docs/features/software-templates/writing-templates.md b/docs/features/software-templates/writing-templates.md index 7019ecfb28..aa45d268d6 100644 --- a/docs/features/software-templates/writing-templates.md +++ b/docs/features/software-templates/writing-templates.md @@ -231,8 +231,53 @@ spec: inputType: tel ``` +### Using Secrets + +You may want to mark thinks as secret and make sure that these values are protected and not available through REST endpoints. You can do this by using the built in `ui:field: Secret`. + +You can define this property as any normal parameter, however the consumption of this parameter will not be available through `${{ parameters.myKey }}` you will need to use `${{ secrets.myKey }}` instead in the `template.yaml`. + +Parameters will be automatically masked in the review step. + +```yaml +apiVersion: scaffolder.backstage.io/v1beta3 +kind: Template +metadata: + name: v1beta3-demo + title: Test Action template + description: scaffolder v1beta3 template demo +spec: + owner: backstage/techdocs-core + type: service + + parameters: + - title: Authenticaion + description: Provide authentication for the resource + required: + - username + - password + properties: + username: + type: string + # use the built in Secret field extension + ui:field: Secret + password: + type: string + ui:field: Secret + + steps: + - id: setupAuthentication + action: auth:create + input: + # make sure to use ${{ secret.parameterName }} to reference these values + username: ${{ secrets.username }} + password: ${{ secrets.password }} +``` + ### Hide or mask sensitive data on Review step +> Note: this approach is soon to be deprecated, please mark things as secret by using the `Secret` field extension instead as metioned above. + Sometimes, specially in custom fields, you collect some data on Create form that must not be shown to the user on Review step. To hide or mask this data, you can use `ui:widget: password` or set some properties of `ui:backstage`: From 33edf500908eb72eebdaef4a604986137ef5d8ad Mon Sep 17 00:00:00 2001 From: blam Date: Mon, 18 Dec 2023 14:20:34 +0100 Subject: [PATCH 251/275] chore: added chantgeset Signed-off-by: blam --- .changeset/itchy-otters-switch.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/itchy-otters-switch.md diff --git a/.changeset/itchy-otters-switch.md b/.changeset/itchy-otters-switch.md new file mode 100644 index 0000000000..c55de1c700 --- /dev/null +++ b/.changeset/itchy-otters-switch.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': minor +--- + +Added support for dealing with user provided secrets using a new field extension `ui:field: Secret` From 3855d2a1cd0495b05ce2b1504d6db12188bf1776 Mon Sep 17 00:00:00 2001 From: blam Date: Mon, 18 Dec 2023 14:25:53 +0100 Subject: [PATCH 252/275] chore: default the value so that the form looks ok Signed-off-by: blam --- plugins/scaffolder/src/components/fields/Secret/Secret.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/scaffolder/src/components/fields/Secret/Secret.tsx b/plugins/scaffolder/src/components/fields/Secret/Secret.tsx index 2933a405f1..98632ae135 100644 --- a/plugins/scaffolder/src/components/fields/Secret/Secret.tsx +++ b/plugins/scaffolder/src/components/fields/Secret/Secret.tsx @@ -20,7 +20,7 @@ import { ScaffolderField } from '@backstage/plugin-scaffolder-react/alpha'; import { Input, InputLabel } from '@material-ui/core'; export const Secret = (props: ScaffolderRJSFFieldProps) => { - const { setSecrets } = useTemplateSecrets(); + const { setSecrets, secrets } = useTemplateSecrets(); const { name, schema: { title, description }, @@ -55,6 +55,7 @@ export const Secret = (props: ScaffolderRJSFFieldProps) => { ); setSecrets({ [name]: e.target?.value }); }} + value={secrets[name] ?? ''} type="password" autoComplete="off" /> From 82af648de3251c3418ad7f9ffcc7866144a01948 Mon Sep 17 00:00:00 2001 From: blam Date: Mon, 18 Dec 2023 14:34:02 +0100 Subject: [PATCH 253/275] chore: reset some testing files and fix docs Signed-off-by: blam --- .../software-templates/writing-templates.md | 2 +- .../sample-templates/all-templates.yaml | 1 - .../sample-templates/template.yaml | 19 ------------------- 3 files changed, 1 insertion(+), 21 deletions(-) delete mode 100644 plugins/scaffolder-backend/sample-templates/template.yaml diff --git a/docs/features/software-templates/writing-templates.md b/docs/features/software-templates/writing-templates.md index aa45d268d6..e05923de78 100644 --- a/docs/features/software-templates/writing-templates.md +++ b/docs/features/software-templates/writing-templates.md @@ -276,7 +276,7 @@ spec: ### Hide or mask sensitive data on Review step -> Note: this approach is soon to be deprecated, please mark things as secret by using the `Secret` field extension instead as metioned above. +> Note: this approach is soon to be deprecated, please mark things as secret by using the `Secret` field extension instead as mentioned above. Sometimes, specially in custom fields, you collect some data on Create form that must not be shown to the user on Review step. To hide or mask this data, you can diff --git a/plugins/scaffolder-backend/sample-templates/all-templates.yaml b/plugins/scaffolder-backend/sample-templates/all-templates.yaml index fb2db2e608..6637c9479b 100644 --- a/plugins/scaffolder-backend/sample-templates/all-templates.yaml +++ b/plugins/scaffolder-backend/sample-templates/all-templates.yaml @@ -6,7 +6,6 @@ metadata: spec: targets: - ./remote-templates.yaml - - ./template.yaml # For local development of a template, you can reference your local templates here. # Examples: # diff --git a/plugins/scaffolder-backend/sample-templates/template.yaml b/plugins/scaffolder-backend/sample-templates/template.yaml deleted file mode 100644 index 8d0ec0316f..0000000000 --- a/plugins/scaffolder-backend/sample-templates/template.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: scaffolder.backstage.io/v1beta3 -kind: Template -metadata: - name: test - title: Test template -spec: - parameters: - - title: Do something - required: - - myKey - properties: - myKey: - title: My key - description: asd - type: string - ui:field: Secret - steps: [] - type: service - \ No newline at end of file From 2263fab8b28dc2f7894c55b8eef0cbbc2165cbcb Mon Sep 17 00:00:00 2001 From: blam Date: Mon, 18 Dec 2023 14:43:30 +0100 Subject: [PATCH 254/275] chore: fixing formatting Signed-off-by: blam --- packages/catalog-model/examples/acme/backstage-group.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/catalog-model/examples/acme/backstage-group.yaml b/packages/catalog-model/examples/acme/backstage-group.yaml index f04830e475..0372eedab7 100644 --- a/packages/catalog-model/examples/acme/backstage-group.yaml +++ b/packages/catalog-model/examples/acme/backstage-group.yaml @@ -11,5 +11,3 @@ spec: picture: https://api.dicebear.com/7.x/identicon/svg?seed=Fluffy&backgroundColor=ffdfbf parent: infrastructure children: [team-a, team-b] - - From ae75bc12c8bf696d658a80703d31a594a2e01334 Mon Sep 17 00:00:00 2001 From: blam Date: Mon, 18 Dec 2023 15:09:11 +0100 Subject: [PATCH 255/275] chore: update the api-reports Signed-off-by: blam --- plugins/scaffolder/api-report.md | 4 ++++ plugins/scaffolder/src/components/fields/Secret/Secret.tsx | 3 +++ 2 files changed, 7 insertions(+) diff --git a/plugins/scaffolder/api-report.md b/plugins/scaffolder/api-report.md index 4df1eff430..9f1240f48b 100644 --- a/plugins/scaffolder/api-report.md +++ b/plugins/scaffolder/api-report.md @@ -40,6 +40,7 @@ import { ScaffolderDryRunResponse as ScaffolderDryRunResponse_2 } from '@backsta import { ScaffolderGetIntegrationsListOptions as ScaffolderGetIntegrationsListOptions_2 } from '@backstage/plugin-scaffolder-react'; import { ScaffolderGetIntegrationsListResponse as ScaffolderGetIntegrationsListResponse_2 } from '@backstage/plugin-scaffolder-react'; import { ScaffolderOutputLink } from '@backstage/plugin-scaffolder-react'; +import { ScaffolderRJSFFieldProps } from '@backstage/plugin-scaffolder-react'; import { ScaffolderScaffoldOptions as ScaffolderScaffoldOptions_2 } from '@backstage/plugin-scaffolder-react'; import { ScaffolderScaffoldResponse as ScaffolderScaffoldResponse_2 } from '@backstage/plugin-scaffolder-react'; import { ScaffolderStreamLogsOptions as ScaffolderStreamLogsOptions_2 } from '@backstage/plugin-scaffolder-react'; @@ -581,6 +582,9 @@ export type ScaffolderTaskStatus = ScaffolderTaskStatus_2; // @public @deprecated (undocumented) export type ScaffolderUseTemplateSecrets = ScaffolderUseTemplateSecrets_2; +// @public (undocumented) +export const Secret: (props: ScaffolderRJSFFieldProps) => React_2.JSX.Element; + // @public (undocumented) export const TaskPage: (props: { TemplateOutputsComponent?: React_2.ComponentType<{ diff --git a/plugins/scaffolder/src/components/fields/Secret/Secret.tsx b/plugins/scaffolder/src/components/fields/Secret/Secret.tsx index 98632ae135..58dd18476f 100644 --- a/plugins/scaffolder/src/components/fields/Secret/Secret.tsx +++ b/plugins/scaffolder/src/components/fields/Secret/Secret.tsx @@ -19,6 +19,9 @@ import { ScaffolderRJSFFieldProps } from '@backstage/plugin-scaffolder-react'; import { ScaffolderField } from '@backstage/plugin-scaffolder-react/alpha'; import { Input, InputLabel } from '@material-ui/core'; +/** + * @public + */ export const Secret = (props: ScaffolderRJSFFieldProps) => { const { setSecrets, secrets } = useTemplateSecrets(); const { From 6349a669fab2c2957ae145395a94580161e9f171 Mon Sep 17 00:00:00 2001 From: Andre Wanlin <67169551+awanlin@users.noreply.github.com> Date: Mon, 18 Dec 2023 08:28:36 -0600 Subject: [PATCH 256/275] Update docs/backend-system/building-backends/08-migrating.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Signed-off-by: Andre Wanlin <67169551+awanlin@users.noreply.github.com> --- docs/backend-system/building-backends/08-migrating.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/backend-system/building-backends/08-migrating.md b/docs/backend-system/building-backends/08-migrating.md index 4f6575c805..6591ba5632 100644 --- a/docs/backend-system/building-backends/08-migrating.md +++ b/docs/backend-system/building-backends/08-migrating.md @@ -514,7 +514,7 @@ backend.add( For `MicrosoftGraphOrgReaderProcessor`, first migrate to `MicrosoftGraphOrgEntityProvider` -To migrate `MicrosoftGraphOrgEntityProvider` to the new backend system, add a reference to `@backstage/plugin-catalog-backend-module-github-org`. +To migrate `MicrosoftGraphOrgEntityProvider` to the new backend system, add a reference to `@backstage/plugin-catalog-backend-module-msgraph`. ```ts title="packages/backend/src/index.ts" backend.add(import('@backstage/plugin-catalog-backend/alpha')); From e80b311c1ab1f8f4c26e597d44ff079f41b5a8e0 Mon Sep 17 00:00:00 2001 From: Andre Wanlin <67169551+awanlin@users.noreply.github.com> Date: Mon, 18 Dec 2023 08:28:46 -0600 Subject: [PATCH 257/275] Update docs/backend-system/building-backends/08-migrating.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Signed-off-by: Andre Wanlin <67169551+awanlin@users.noreply.github.com> --- docs/backend-system/building-backends/08-migrating.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/backend-system/building-backends/08-migrating.md b/docs/backend-system/building-backends/08-migrating.md index 6591ba5632..ca8f628c05 100644 --- a/docs/backend-system/building-backends/08-migrating.md +++ b/docs/backend-system/building-backends/08-migrating.md @@ -523,7 +523,7 @@ backend.add(import('@backstage/plugin-catalog-backend-module-msgraph/alpha')); /* highlight-add-end */ ``` -If you were providing a `schedule` in code, this now needs to be set via configuration +If you were providing a `schedule` in code, this now needs to be set via configuration. All other Microsoft Graph configuration in `app-config.yaml` remains the same. ```yaml title="app-config.yaml" From 639ed772f7c1876636ab7d5e4dc5ef1c5f9f30f8 Mon Sep 17 00:00:00 2001 From: Andre Wanlin <67169551+awanlin@users.noreply.github.com> Date: Mon, 18 Dec 2023 08:28:57 -0600 Subject: [PATCH 258/275] Update docs/backend-system/building-backends/08-migrating.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Signed-off-by: Andre Wanlin <67169551+awanlin@users.noreply.github.com> --- docs/backend-system/building-backends/08-migrating.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/backend-system/building-backends/08-migrating.md b/docs/backend-system/building-backends/08-migrating.md index ca8f628c05..f866cb63d1 100644 --- a/docs/backend-system/building-backends/08-migrating.md +++ b/docs/backend-system/building-backends/08-migrating.md @@ -325,7 +325,7 @@ catalog: #### Open API -`InternalOpenApiDocumentationProvider` have not yet been migrated to the new backend system. +`InternalOpenApiDocumentationProvider` has not yet been migrated to the new backend system. See [Other Catalog Extensions](#other-catalog-extensions) for how to use this in the new backend system. #### Bitbucket From 424317b8291ef11f5c0ff2fe27fde7a75a6b0c01 Mon Sep 17 00:00:00 2001 From: npiyush97 Date: Mon, 18 Dec 2023 20:09:19 +0530 Subject: [PATCH 259/275] fixed test Signed-off-by: npiyush97 --- .../scaffolder-backend-module-github/src/actions/github.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/scaffolder-backend-module-github/src/actions/github.test.ts b/plugins/scaffolder-backend-module-github/src/actions/github.test.ts index c22d8ca7c3..a2a8e11e15 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/github.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/github.test.ts @@ -564,7 +564,7 @@ describe('publish:github', () => { defaultBranch: 'master', auth: { username: 'x-access-token', password: 'tokenlols' }, logger: mockContext.logger, - commitMessage: 'initial commit', + commitMessage: 'Test commit message', gitAuthorInfo: { email: undefined, name: undefined }, }); }); From 63aab7c050a992e64d9fd52e1fc5caa5023c51fe Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 18 Dec 2023 14:26:42 +0100 Subject: [PATCH 260/275] Update docs/frontend-system/building-plugins/testing.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Signed-off-by: Patrik Oldsberg --- docs/frontend-system/building-plugins/testing.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/frontend-system/building-plugins/testing.md b/docs/frontend-system/building-plugins/testing.md index 8177724ae1..dbe883c55b 100644 --- a/docs/frontend-system/building-plugins/testing.md +++ b/docs/frontend-system/building-plugins/testing.md @@ -31,7 +31,7 @@ describe('Entity details component', () => { await renderInTestApp(); await expect( - screen.getByText('The entity "test" is owned by "tools"'), + screen.findByText('The entity "test" is owned by "tools"'), ).resolves.toBeInTheDocument(); }); }); @@ -75,7 +75,7 @@ describe('Entity details component', () => { ); await expect( - screen.getByText('The entity "test" is owned by "tools"'), + screen.findByText('The entity "test" is owned by "tools"'), ).resolves.toBeInTheDocument(); }); }); From 6f280fa01a0e5eb0ef8e0bc278165b145231a396 Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Mon, 18 Dec 2023 16:24:45 +0100 Subject: [PATCH 261/275] fix search issue analytics tracking Signed-off-by: Emma Indal --- .changeset/pretty-timers-drive.md | 5 ++ .../src/context/SearchContext.test.tsx | 57 +++++++++++++++++++ .../src/context/SearchContext.tsx | 4 +- 3 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 .changeset/pretty-timers-drive.md diff --git a/.changeset/pretty-timers-drive.md b/.changeset/pretty-timers-drive.md new file mode 100644 index 0000000000..bf9f57261e --- /dev/null +++ b/.changeset/pretty-timers-drive.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-search-react': patch +--- + +Capture analytics even when number of results is not available, since the total result count is not something that is always available for all search engines and configurations. diff --git a/plugins/search-react/src/context/SearchContext.test.tsx b/plugins/search-react/src/context/SearchContext.test.tsx index 39a9f09ef4..58fde35667 100644 --- a/plugins/search-react/src/context/SearchContext.test.tsx +++ b/plugins/search-react/src/context/SearchContext.test.tsx @@ -479,4 +479,61 @@ describe('SearchContext', () => { }); }); }); + + it('captures analytics events even if number of results does not exist', async () => { + const analyticsApiMock = { + captureEvent: jest.fn(), + } satisfies typeof analyticsApiRef.T; + + searchApiMock.query.mockResolvedValue({ + results: [], + }); + + const { result } = renderHook(() => useSearch(), { + wrapper: ({ children }) => { + const configApiMock = new MockConfigApi({}); + return ( + + + {children} + + + ); + }, + }); + + await waitFor(() => { + expect(result.current).toEqual(expect.objectContaining(initialState)); + }); + + const term = 'term'; + + await act(async () => { + result.current.setTerm(term); + }); + + await waitFor(() => { + expect(searchApiMock.query).toHaveBeenLastCalledWith({ + term: 'term', + types: ['*'], + filters: {}, + }); + expect(analyticsApiMock.captureEvent).toHaveBeenCalledWith({ + action: 'search', + subject: 'term', + value: undefined, + context: { + extension: 'App', + pluginId: 'root', + routeRef: 'unknown', + }, + }); + }); + }); }); diff --git a/plugins/search-react/src/context/SearchContext.tsx b/plugins/search-react/src/context/SearchContext.tsx index 6ce18501d9..f8140e2f19 100644 --- a/plugins/search-react/src/context/SearchContext.tsx +++ b/plugins/search-react/src/context/SearchContext.tsx @@ -138,9 +138,9 @@ const useSearchContextValue = ( pageLimit, pageCursor, }); - if (term && resultSet.numberOfResults !== undefined) { + if (term) { analytics.captureEvent('search', term, { - value: resultSet.numberOfResults, + value: result.value?.numberOfResults ?? undefined, }); } return resultSet; From c963bcee4cc142656b341b981f37e26ad80693b5 Mon Sep 17 00:00:00 2001 From: blam Date: Mon, 18 Dec 2023 17:22:02 +0100 Subject: [PATCH 262/275] chore: improve the implementation a little bit Signed-off-by: blam --- .../src/next/components/Stepper/Stepper.tsx | 31 +++++++++++++++++-- .../SecretInput.test.tsx} | 6 ++-- .../SecretInput.tsx} | 19 ++---------- .../fields/{Secret => SecretInput}/index.tsx | 2 +- .../scaffolder/src/components/fields/index.ts | 1 - plugins/scaffolder/src/extensions/default.ts | 5 +-- 6 files changed, 38 insertions(+), 26 deletions(-) rename plugins/scaffolder/src/components/fields/{Secret/Secret.test.tsx => SecretInput/SecretInput.test.tsx} (96%) rename plugins/scaffolder/src/components/fields/{Secret/Secret.tsx => SecretInput/SecretInput.tsx} (70%) rename plugins/scaffolder/src/components/fields/{Secret => SecretInput}/index.tsx (95%) diff --git a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx index 5b41163ae4..70071721fa 100644 --- a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx +++ b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx @@ -24,7 +24,7 @@ import { LinearProgress, } from '@material-ui/core'; import { type IChangeEvent } from '@rjsf/core'; -import { ErrorSchema } from '@rjsf/utils'; +import { ErrorSchema, ValidatorType } from '@rjsf/utils'; import React, { useCallback, useMemo, @@ -49,6 +49,7 @@ import { LayoutOptions, FieldExtensionOptions, FormProps, + useTemplateSecrets, } from '@backstage/plugin-scaffolder-react'; import { ReviewStepProps } from '@backstage/plugin-scaffolder-react'; @@ -102,6 +103,7 @@ export const Stepper = (stepperProps: StepperProps) => { reviewButtonText = 'Review', } = components; const analytics = useAnalytics(); + const { secrets } = useTemplateSecrets(); const { presentation, steps } = useTemplateSchema(props.manifest); const apiHolder = useApiHolder(); const [activeStep, setActiveStep] = useState(0); @@ -111,6 +113,31 @@ export const Stepper = (stepperProps: StepperProps) => { const [errors, setErrors] = useState(); const styles = useStyles(); + const stringifiedSecrets = JSON.stringify(secrets); + + // Because secrets can be defined in the schema, we need to make sure that they + // are included in the validation process. So we merge the secrets and the formData + // together in validation. + const customValidator = useMemo( + () => ({ + isValid: (schema, formData, rootSchema) => + validator.isValid(schema, { ...formData, ...secrets }, rootSchema), + rawValidation: (schema, formData) => + validator.rawValidation(schema, { ...formData, ...secrets }), + validateFormData: (formData, schema, customFormats, transformErrors) => + validator.validateFormData( + { ...formData, ...secrets }, + schema, + customFormats, + transformErrors, + ), + // @deprecated + toErrorList: validator.toErrorList, + }), + // eslint-disable-next-line react-hooks/exhaustive-deps + [secrets, stringifiedSecrets], + ); + const extensions = useMemo(() => { return Object.fromEntries( props.extensions.map(({ name, component }) => [name, component]), @@ -220,7 +247,7 @@ export const Stepper = (stepperProps: StepperProps) => { {/* eslint-disable-next-line no-nested-ternary */} {activeStep < steps.length ? ( ', () => { 'ui:field': 'Secret', }} fields={{ - Secret: Secret, + Secret: SecretInput, }} onSubmit={onSubmit} /> @@ -86,7 +86,7 @@ describe('', () => { }, }} fields={{ - Secret: Secret, + Secret: SecretInput, }} onSubmit={onSubmit} /> diff --git a/plugins/scaffolder/src/components/fields/Secret/Secret.tsx b/plugins/scaffolder/src/components/fields/SecretInput/SecretInput.tsx similarity index 70% rename from plugins/scaffolder/src/components/fields/Secret/Secret.tsx rename to plugins/scaffolder/src/components/fields/SecretInput/SecretInput.tsx index 58dd18476f..d68216650b 100644 --- a/plugins/scaffolder/src/components/fields/Secret/Secret.tsx +++ b/plugins/scaffolder/src/components/fields/SecretInput/SecretInput.tsx @@ -19,10 +19,7 @@ import { ScaffolderRJSFFieldProps } from '@backstage/plugin-scaffolder-react'; import { ScaffolderField } from '@backstage/plugin-scaffolder-react/alpha'; import { Input, InputLabel } from '@material-ui/core'; -/** - * @public - */ -export const Secret = (props: ScaffolderRJSFFieldProps) => { +export const SecretInput = (props: ScaffolderRJSFFieldProps) => { const { setSecrets, secrets } = useTemplateSecrets(); const { name, @@ -30,7 +27,6 @@ export const Secret = (props: ScaffolderRJSFFieldProps) => { rawErrors, disabled, errors, - onChange, required, } = props; @@ -46,18 +42,7 @@ export const Secret = (props: ScaffolderRJSFFieldProps) => { { - // TODO(blam): this is a bit of a hack. We need to to probably figure out - // how to provide our own validator that can filter out the secrets from the - // jsonschema, or merge the secrets with the formData for validation? - // Makes the review step a little cleaner with this though. - onChange( - Array(e.target?.value.length ?? 0) - .fill('*') - .join(''), - ); - setSecrets({ [name]: e.target?.value }); - }} + onChange={e => setSecrets({ [name]: e.target?.value })} value={secrets[name] ?? ''} type="password" autoComplete="off" diff --git a/plugins/scaffolder/src/components/fields/Secret/index.tsx b/plugins/scaffolder/src/components/fields/SecretInput/index.tsx similarity index 95% rename from plugins/scaffolder/src/components/fields/Secret/index.tsx rename to plugins/scaffolder/src/components/fields/SecretInput/index.tsx index e28248ef7d..859a04a4d3 100644 --- a/plugins/scaffolder/src/components/fields/Secret/index.tsx +++ b/plugins/scaffolder/src/components/fields/SecretInput/index.tsx @@ -13,4 +13,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export * from './Secret'; +export * from './SecretInput'; diff --git a/plugins/scaffolder/src/components/fields/index.ts b/plugins/scaffolder/src/components/fields/index.ts index e29a4d791c..7f119f27be 100644 --- a/plugins/scaffolder/src/components/fields/index.ts +++ b/plugins/scaffolder/src/components/fields/index.ts @@ -19,6 +19,5 @@ export * from './RepoUrlPicker'; export * from './OwnedEntityPicker'; export * from './EntityTagsPicker'; export * from './MyGroupsPicker'; -export * from './Secret'; export { type FieldSchema, makeFieldSchemaFromZod } from './utils'; diff --git a/plugins/scaffolder/src/extensions/default.ts b/plugins/scaffolder/src/extensions/default.ts index ef4a701e86..2e4b7032de 100644 --- a/plugins/scaffolder/src/extensions/default.ts +++ b/plugins/scaffolder/src/extensions/default.ts @@ -43,7 +43,8 @@ import { MyGroupsPicker, MyGroupsPickerSchema, } from '../components/fields/MyGroupsPicker/MyGroupsPicker'; -import { Secret } from '../components'; + +import { SecretInput } from '../components/fields/SecretInput'; export const DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS = [ { @@ -84,7 +85,7 @@ export const DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS = [ schema: MyGroupsPickerSchema, }, { - component: Secret, + component: SecretInput, name: 'Secret', }, ]; From 640a7cc5d134c7ee33269296b327da18e2a27295 Mon Sep 17 00:00:00 2001 From: blam Date: Mon, 18 Dec 2023 17:25:17 +0100 Subject: [PATCH 263/275] chore: fix Secret field extension export Signed-off-by: blam --- plugins/scaffolder/api-report.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/plugins/scaffolder/api-report.md b/plugins/scaffolder/api-report.md index 9f1240f48b..4df1eff430 100644 --- a/plugins/scaffolder/api-report.md +++ b/plugins/scaffolder/api-report.md @@ -40,7 +40,6 @@ import { ScaffolderDryRunResponse as ScaffolderDryRunResponse_2 } from '@backsta import { ScaffolderGetIntegrationsListOptions as ScaffolderGetIntegrationsListOptions_2 } from '@backstage/plugin-scaffolder-react'; import { ScaffolderGetIntegrationsListResponse as ScaffolderGetIntegrationsListResponse_2 } from '@backstage/plugin-scaffolder-react'; import { ScaffolderOutputLink } from '@backstage/plugin-scaffolder-react'; -import { ScaffolderRJSFFieldProps } from '@backstage/plugin-scaffolder-react'; import { ScaffolderScaffoldOptions as ScaffolderScaffoldOptions_2 } from '@backstage/plugin-scaffolder-react'; import { ScaffolderScaffoldResponse as ScaffolderScaffoldResponse_2 } from '@backstage/plugin-scaffolder-react'; import { ScaffolderStreamLogsOptions as ScaffolderStreamLogsOptions_2 } from '@backstage/plugin-scaffolder-react'; @@ -582,9 +581,6 @@ export type ScaffolderTaskStatus = ScaffolderTaskStatus_2; // @public @deprecated (undocumented) export type ScaffolderUseTemplateSecrets = ScaffolderUseTemplateSecrets_2; -// @public (undocumented) -export const Secret: (props: ScaffolderRJSFFieldProps) => React_2.JSX.Element; - // @public (undocumented) export const TaskPage: (props: { TemplateOutputsComponent?: React_2.ComponentType<{ From b7902a715d2fb6e187f1aee40f6bc0ace7126825 Mon Sep 17 00:00:00 2001 From: blam Date: Mon, 18 Dec 2023 17:27:50 +0100 Subject: [PATCH 264/275] chore: fixing docs Signed-off-by: blam --- docs/features/software-templates/writing-templates.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/features/software-templates/writing-templates.md b/docs/features/software-templates/writing-templates.md index e05923de78..35458446c2 100644 --- a/docs/features/software-templates/writing-templates.md +++ b/docs/features/software-templates/writing-templates.md @@ -233,9 +233,9 @@ spec: ### Using Secrets -You may want to mark thinks as secret and make sure that these values are protected and not available through REST endpoints. You can do this by using the built in `ui:field: Secret`. +You may want to mark things as secret and make sure that these values are protected and not available through REST endpoints. You can do this by using the built in `ui:field: Secret`. -You can define this property as any normal parameter, however the consumption of this parameter will not be available through `${{ parameters.myKey }}` you will need to use `${{ secrets.myKey }}` instead in the `template.yaml`. +You can define this property as any normal parameter, however the consumption of this parameter will not be available through `${{ parameters.myKey }}` you will instead need to use `${{ secrets.myKey }}` in your `template.yaml`. Parameters will be automatically masked in the review step. @@ -269,7 +269,7 @@ spec: - id: setupAuthentication action: auth:create input: - # make sure to use ${{ secret.parameterName }} to reference these values + # make sure to use ${{ secrets.parameterName }} to reference these values username: ${{ secrets.username }} password: ${{ secrets.password }} ``` From 66401c1f27c8c842fb7906ac39b7be956a3485ea Mon Sep 17 00:00:00 2001 From: rui ma Date: Tue, 19 Dec 2023 12:13:13 +0800 Subject: [PATCH 265/275] fix: when use LogViewer with big size(more then 30M maybe) logs cause maximun call stack error Signed-off-by: rui ma --- .../core-components/src/components/LogViewer/AnsiProcessor.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core-components/src/components/LogViewer/AnsiProcessor.ts b/packages/core-components/src/components/LogViewer/AnsiProcessor.ts index d0f835a70e..bcd5af7ced 100644 --- a/packages/core-components/src/components/LogViewer/AnsiProcessor.ts +++ b/packages/core-components/src/components/LogViewer/AnsiProcessor.ts @@ -117,7 +117,7 @@ export class AnsiProcessor { return this.lines; } - if (text.startsWith(this.text)) { + if (this.text && text.startsWith(this.text)) { const lastLineIndex = this.lines.length > 0 ? this.lines.length - 1 : 0; const lastLine = this.lines[lastLineIndex] ?? new AnsiLine(); const lastChunk = lastLine.lastChunk(); @@ -130,7 +130,7 @@ export class AnsiProcessor { lastLine.replaceLastChunk(newLines[0]?.chunks); this.lines[lastLineIndex] = lastLine; - this.lines.push(...newLines.slice(1)); + this.lines = this.lines.concat(newLines.slice(1)); } else { this.lines = this.processLines(text); } From 752df9315b1ac7c79e4e4de6c8865b170d5c6725 Mon Sep 17 00:00:00 2001 From: rui ma Date: Tue, 19 Dec 2023 12:17:07 +0800 Subject: [PATCH 266/275] fix: add changeset Signed-off-by: rui ma --- .changeset/honest-hounds-exist.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/honest-hounds-exist.md diff --git a/.changeset/honest-hounds-exist.md b/.changeset/honest-hounds-exist.md new file mode 100644 index 0000000000..56fb9a2734 --- /dev/null +++ b/.changeset/honest-hounds-exist.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': patch +--- + +when use LogViewer with big size(more then 30M maybe) logs cause maximun call stack error From 7c4ded2515042a1f9d14206acc0406e4cdc2ef77 Mon Sep 17 00:00:00 2001 From: blam Date: Tue, 19 Dec 2023 09:37:35 +0100 Subject: [PATCH 267/275] chore: add the other package to changeset Signed-off-by: blam --- .changeset/itchy-otters-switch.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.changeset/itchy-otters-switch.md b/.changeset/itchy-otters-switch.md index c55de1c700..72869032f2 100644 --- a/.changeset/itchy-otters-switch.md +++ b/.changeset/itchy-otters-switch.md @@ -1,5 +1,6 @@ --- '@backstage/plugin-scaffolder': minor +'@backstage/plugin-scaffolder-react': minor --- Added support for dealing with user provided secrets using a new field extension `ui:field: Secret` From 9df2ebc76008e6030f6079075de9f7a6a15f9647 Mon Sep 17 00:00:00 2001 From: Ben Lambert Date: Tue, 19 Dec 2023 09:58:54 +0100 Subject: [PATCH 268/275] Update plugins/scaffolder/src/components/fields/SecretInput/SecretInput.test.tsx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Signed-off-by: Ben Lambert Signed-off-by: blam --- .../src/components/fields/SecretInput/SecretInput.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/scaffolder/src/components/fields/SecretInput/SecretInput.test.tsx b/plugins/scaffolder/src/components/fields/SecretInput/SecretInput.test.tsx index 1765c42f16..a73f6a8fda 100644 --- a/plugins/scaffolder/src/components/fields/SecretInput/SecretInput.test.tsx +++ b/plugins/scaffolder/src/components/fields/SecretInput/SecretInput.test.tsx @@ -24,7 +24,7 @@ import { Form } from '@backstage/plugin-scaffolder-react/alpha'; import validator from '@rjsf/validator-ajv8'; import { fireEvent, act } from '@testing-library/react'; -describe('', () => { +describe('', () => { const SecretsComponent = () => { const { secrets } = useTemplateSecrets(); return ( From 2fa5f646b2408f92b2c64f3a6bfb055c717c5391 Mon Sep 17 00:00:00 2001 From: blam Date: Tue, 19 Dec 2023 10:29:33 +0100 Subject: [PATCH 269/275] feat: Stepper needs to be wrapped in the SecretsContext Signed-off-by: blam --- .../next/components/Stepper/Stepper.test.tsx | 127 +++++++++++------- .../src/next/components/Workflow/Workflow.tsx | 20 +-- .../fields/SecretInput/SecretInput.test.tsx | 37 ----- 3 files changed, 86 insertions(+), 98 deletions(-) diff --git a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.test.tsx b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.test.tsx index 2bb66fd782..d7e271f8b3 100644 --- a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.test.tsx +++ b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.test.tsx @@ -21,6 +21,7 @@ import { act, fireEvent } from '@testing-library/react'; import type { RJSFValidationError } from '@rjsf/utils'; import { JsonValue } from '@backstage/types'; import { FieldExtensionComponentProps } from '../../../extensions'; +import { SecretsContextProvider } from '../../../secrets'; import { LayoutTemplate } from '../../../layouts'; describe('Stepper', () => { @@ -34,7 +35,9 @@ describe('Stepper', () => { }; const { getByText } = await renderInTestApp( - , + + + , ); for (const step of manifest.steps) { @@ -52,7 +55,9 @@ describe('Stepper', () => { }; const { getByRole } = await renderInTestApp( - , + + + , ); expect(getByRole('button', { name: 'Next' })).toBeInTheDocument(); @@ -92,7 +97,9 @@ describe('Stepper', () => { }; const { getByRole } = await renderInTestApp( - , + + + , ); await fireEvent.change(getByRole('textbox', { name: 'name' }), { @@ -140,7 +147,9 @@ describe('Stepper', () => { }; const { getByRole, getByLabelText } = await renderInTestApp( - , + + + , ); await fireEvent.change(getByRole('textbox', { name: 'name' }), { @@ -219,14 +228,16 @@ describe('Stepper', () => { }); const { getByRole } = await renderInTestApp( - , + + + , ); await fireEvent.change(getByRole('textbox', { name: 'repo' }), { @@ -275,11 +286,13 @@ describe('Stepper', () => { }; const { getByText } = await renderInTestApp( - , + + + , ); expect(getByText('im a custom field extension')).toBeInTheDocument(); @@ -308,17 +321,19 @@ describe('Stepper', () => { }; const { getByRole } = await renderInTestApp( - new Promise(r => setTimeout(r, 1000)), - }, - ]} - onCreate={jest.fn()} - />, + + new Promise(r => setTimeout(r, 1000)), + }, + ]} + onCreate={jest.fn()} + /> + , ); act(() => { @@ -356,12 +371,14 @@ describe('Stepper', () => { }; const { getByText, getByRole } = await renderInTestApp( - , + + + , ); await fireEvent.change(getByRole('textbox', { name: 'postcode' }), { @@ -401,7 +418,9 @@ describe('Stepper', () => { }); const { getByRole } = await renderInTestApp( - , + + + , ); expect(getByRole('textbox', { name: 'firstName' })).toHaveValue('John'); @@ -429,7 +448,9 @@ describe('Stepper', () => { }); const { getByRole } = await renderInTestApp( - , + + + , ); await act(async () => { @@ -464,15 +485,17 @@ describe('Stepper', () => { }; const { getByRole } = await renderInTestApp( - Make, - reviewButtonText: Inspect, - }} - />, + + Make, + reviewButtonText: Inspect, + }} + /> + , ); await act(async () => { @@ -516,12 +539,14 @@ describe('Stepper', () => { }; const { getByText, getByRole } = await renderInTestApp( - , + + + , ); expect(getByText('A Scaffolder Layout')).toBeInTheDocument(); diff --git a/plugins/scaffolder-react/src/next/components/Workflow/Workflow.tsx b/plugins/scaffolder-react/src/next/components/Workflow/Workflow.tsx index c6030930c5..c2ea544463 100644 --- a/plugins/scaffolder-react/src/next/components/Workflow/Workflow.tsx +++ b/plugins/scaffolder-react/src/next/components/Workflow/Workflow.tsx @@ -111,11 +111,13 @@ export const Workflow = (workflowProps: WorkflowProps): JSX.Element | null => { noPadding titleTypographyProps={{ component: 'h2' }} > - + + + )} @@ -123,10 +125,8 @@ export const Workflow = (workflowProps: WorkflowProps): JSX.Element | null => { }; /** + * TODO(blam): work out what we want to do with these components in the new API. + * Should we really have EmbeddableWorkflow -> Workflow -> Stepper -> Form, or should we revisit this? * @alpha */ -export const EmbeddableWorkflow = (props: WorkflowProps) => ( - - - -); +export const EmbeddableWorkflow = Workflow; diff --git a/plugins/scaffolder/src/components/fields/SecretInput/SecretInput.test.tsx b/plugins/scaffolder/src/components/fields/SecretInput/SecretInput.test.tsx index a73f6a8fda..fa810b9d17 100644 --- a/plugins/scaffolder/src/components/fields/SecretInput/SecretInput.test.tsx +++ b/plugins/scaffolder/src/components/fields/SecretInput/SecretInput.test.tsx @@ -32,43 +32,6 @@ describe('', () => { ); }; - it('should set the current form value as a mask for the value entered', async () => { - const mockSecret = 'backstage'; - const onSubmit = jest.fn(); - - const { getByLabelText, getByRole } = await renderInTestApp( - - - - , - ); - - const secretInput = getByLabelText('secret'); - const submitButton = getByRole('button'); - - await act(async () => { - fireEvent.change(secretInput, { target: { value: mockSecret } }); - fireEvent.click(submitButton); - }); - - expect(onSubmit).toHaveBeenCalledWith( - expect.objectContaining({ - formData: '*********', - }), - expect.anything(), - ); - }); - it('should set the secret value to the unmasked value', async () => { const mockSecret = 'backstage'; const onSubmit = jest.fn(); From 857f44cb0321fddf22d52a916200f024343fb044 Mon Sep 17 00:00:00 2001 From: blam Date: Tue, 19 Dec 2023 10:31:26 +0100 Subject: [PATCH 270/275] chore: update changeset Signed-off-by: blam --- .changeset/itchy-otters-switch.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.changeset/itchy-otters-switch.md b/.changeset/itchy-otters-switch.md index 72869032f2..de155a05ea 100644 --- a/.changeset/itchy-otters-switch.md +++ b/.changeset/itchy-otters-switch.md @@ -4,3 +4,5 @@ --- Added support for dealing with user provided secrets using a new field extension `ui:field: Secret` + +The `@alpha` exports of `Stepper` now needs to be wrapped in a `SecretsContextProvider` for access to secrets. From af7bc3eecb3238263d1b9777da809c28254c7983 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 18 Dec 2023 00:47:10 +0100 Subject: [PATCH 271/275] plugin/frontend-*: switch extension namespace from core to app Signed-off-by: Patrik Oldsberg --- .changeset/nine-beers-appear.md | 8 ++ .../src/collectLegacyRoutes.test.tsx | 26 +++--- .../src/convertLegacyApp.test.tsx | 22 ++--- .../core-compat-api/src/convertLegacyApp.ts | 8 +- .../frontend-app-api/src/extensions/Core.tsx | 2 +- .../src/extensions/CoreLayout.tsx | 4 +- .../src/extensions/CoreNav.tsx | 4 +- .../src/extensions/CoreRouter.tsx | 4 +- .../src/extensions/CoreRoutes.tsx | 4 +- .../extractRouteInfoFromAppNode.test.ts | 2 +- .../src/tree/createAppTree.test.ts | 16 ++-- .../src/tree/createAppTree.ts | 4 +- .../src/tree/instantiateAppNodeTree.test.ts | 50 +++++------ .../src/tree/readAppExtensionsConfig.test.ts | 82 +++++++++---------- .../src/tree/resolveAppTree.test.ts | 12 +-- .../src/wiring/createApp.test.tsx | 24 +++--- .../frontend-app-api/src/wiring/createApp.tsx | 4 +- .../src/components/ExtensionBoundary.test.tsx | 2 +- .../src/extensions/createApiExtension.test.ts | 4 +- .../src/extensions/createApiExtension.ts | 2 +- .../extensions/createComponentExtension.tsx | 2 +- .../src/extensions/createNavItemExtension.tsx | 2 +- .../createNavLogoExtension.test.tsx | 2 +- .../src/extensions/createNavLogoExtension.tsx | 2 +- .../extensions/createPageExtension.test.tsx | 4 +- .../src/extensions/createPageExtension.tsx | 2 +- .../extensions/createSignInPageExtension.tsx | 2 +- .../src/extensions/createThemeExtension.ts | 2 +- .../createTranslationExtension.test.ts | 6 +- .../extensions/createTranslationExtension.ts | 2 +- .../wiring/createExtensionOverrides.test.ts | 14 ++-- .../src/wiring/createPlugin.test.ts | 8 +- .../src/app/createExtensionTester.test.tsx | 6 +- .../src/app/createExtensionTester.tsx | 12 +-- .../src/app/renderInTestApp.tsx | 2 +- 35 files changed, 180 insertions(+), 172 deletions(-) create mode 100644 .changeset/nine-beers-appear.md diff --git a/.changeset/nine-beers-appear.md b/.changeset/nine-beers-appear.md new file mode 100644 index 0000000000..ee0e81e200 --- /dev/null +++ b/.changeset/nine-beers-appear.md @@ -0,0 +1,8 @@ +--- +'@backstage/core-compat-api': minor +'@backstage/frontend-plugin-api': minor +'@backstage/frontend-test-utils': minor +'@backstage/frontend-app-api': minor +--- + +Switched all core extensions to instead use the namespace `'app'`. diff --git a/packages/core-compat-api/src/collectLegacyRoutes.test.tsx b/packages/core-compat-api/src/collectLegacyRoutes.test.tsx index 862ef68bb5..ed6807514d 100644 --- a/packages/core-compat-api/src/collectLegacyRoutes.test.tsx +++ b/packages/core-compat-api/src/collectLegacyRoutes.test.tsx @@ -60,13 +60,13 @@ describe('collectLegacyRoutes', () => { extensions: [ { id: 'page:score-card', - attachTo: { id: 'core/routes', input: 'routes' }, + attachTo: { id: 'app/routes', input: 'routes' }, disabled: false, defaultConfig: { path: 'score-board' }, }, { id: 'api:plugin.scoringdata.service', - attachTo: { id: 'core', input: 'apis' }, + attachTo: { id: 'app', input: 'apis' }, disabled: false, }, ], @@ -76,13 +76,13 @@ describe('collectLegacyRoutes', () => { extensions: [ { id: 'page:stackstorm', - attachTo: { id: 'core/routes', input: 'routes' }, + attachTo: { id: 'app/routes', input: 'routes' }, disabled: false, defaultConfig: { path: 'stackstorm' }, }, { id: 'api:plugin.stackstorm.service', - attachTo: { id: 'core', input: 'apis' }, + attachTo: { id: 'app', input: 'apis' }, disabled: false, }, ], @@ -92,19 +92,19 @@ describe('collectLegacyRoutes', () => { extensions: [ { id: 'page:puppetDb', - attachTo: { id: 'core/routes', input: 'routes' }, + attachTo: { id: 'app/routes', input: 'routes' }, disabled: false, defaultConfig: { path: 'puppetdb' }, }, { id: 'page:puppetDb/1', - attachTo: { id: 'core/routes', input: 'routes' }, + attachTo: { id: 'app/routes', input: 'routes' }, disabled: false, defaultConfig: { path: 'puppetdb' }, }, { id: 'api:plugin.puppetdb.service', - attachTo: { id: 'core', input: 'apis' }, + attachTo: { id: 'app', input: 'apis' }, disabled: false, }, ], @@ -163,13 +163,13 @@ describe('collectLegacyRoutes', () => { extensions: [ { id: 'page:catalog', - attachTo: { id: 'core/routes', input: 'routes' }, + attachTo: { id: 'app/routes', input: 'routes' }, disabled: false, defaultConfig: { path: 'catalog' }, }, { id: 'page:catalog/1', - attachTo: { id: 'core/routes', input: 'routes' }, + attachTo: { id: 'app/routes', input: 'routes' }, defaultConfig: { path: 'catalog/:namespace/:kind/:name' }, disabled: false, }, @@ -203,7 +203,7 @@ describe('collectLegacyRoutes', () => { { id: 'api:plugin.catalog.service', attachTo: { - id: 'core', + id: 'app', input: 'apis', }, defaultConfig: undefined, @@ -212,7 +212,7 @@ describe('collectLegacyRoutes', () => { { id: 'api:catalog-react.starred-entities', attachTo: { - id: 'core', + id: 'app', input: 'apis', }, defaultConfig: undefined, @@ -221,7 +221,7 @@ describe('collectLegacyRoutes', () => { { id: 'api:plugin.catalog.entity-presentation', attachTo: { - id: 'core', + id: 'app', input: 'apis', }, defaultConfig: undefined, @@ -234,7 +234,7 @@ describe('collectLegacyRoutes', () => { extensions: [ { id: 'api:plugin.scoringdata.service', - attachTo: { id: 'core', input: 'apis' }, + attachTo: { id: 'app', input: 'apis' }, disabled: false, }, ], diff --git a/packages/core-compat-api/src/convertLegacyApp.test.tsx b/packages/core-compat-api/src/convertLegacyApp.test.tsx index a8d6cb2dbc..ef65603c85 100644 --- a/packages/core-compat-api/src/convertLegacyApp.test.tsx +++ b/packages/core-compat-api/src/convertLegacyApp.test.tsx @@ -60,13 +60,13 @@ describe('convertLegacyApp', () => { extensions: [ { id: 'page:score-card', - attachTo: { id: 'core/routes', input: 'routes' }, + attachTo: { id: 'app/routes', input: 'routes' }, disabled: false, defaultConfig: { path: 'score-board' }, }, { id: 'api:plugin.scoringdata.service', - attachTo: { id: 'core', input: 'apis' }, + attachTo: { id: 'app', input: 'apis' }, disabled: false, }, ], @@ -76,13 +76,13 @@ describe('convertLegacyApp', () => { extensions: [ { id: 'page:stackstorm', - attachTo: { id: 'core/routes', input: 'routes' }, + attachTo: { id: 'app/routes', input: 'routes' }, disabled: false, defaultConfig: { path: 'stackstorm' }, }, { id: 'api:plugin.stackstorm.service', - attachTo: { id: 'core', input: 'apis' }, + attachTo: { id: 'app', input: 'apis' }, disabled: false, }, ], @@ -92,19 +92,19 @@ describe('convertLegacyApp', () => { extensions: [ { id: 'page:puppetDb', - attachTo: { id: 'core/routes', input: 'routes' }, + attachTo: { id: 'app/routes', input: 'routes' }, disabled: false, defaultConfig: { path: 'puppetdb' }, }, { id: 'page:puppetDb/1', - attachTo: { id: 'core/routes', input: 'routes' }, + attachTo: { id: 'app/routes', input: 'routes' }, disabled: false, defaultConfig: { path: 'puppetdb' }, }, { id: 'api:plugin.puppetdb.service', - attachTo: { id: 'core', input: 'apis' }, + attachTo: { id: 'app', input: 'apis' }, disabled: false, }, ], @@ -113,13 +113,13 @@ describe('convertLegacyApp', () => { id: undefined, extensions: [ { - id: 'core/layout', - attachTo: { id: 'core', input: 'root' }, + id: 'app/layout', + attachTo: { id: 'app', input: 'root' }, disabled: false, }, { - id: 'core/nav', - attachTo: { id: 'core/layout', input: 'nav' }, + id: 'app/nav', + attachTo: { id: 'app/layout', input: 'nav' }, disabled: true, }, ], diff --git a/packages/core-compat-api/src/convertLegacyApp.ts b/packages/core-compat-api/src/convertLegacyApp.ts index 593a159875..72ce4b5e61 100644 --- a/packages/core-compat-api/src/convertLegacyApp.ts +++ b/packages/core-compat-api/src/convertLegacyApp.ts @@ -103,9 +103,9 @@ export function convertLegacyApp( const [routesEl] = routesEls; const CoreLayoutOverride = createExtension({ - namespace: 'core', + namespace: 'app', name: 'layout', - attachTo: { id: 'core', input: 'root' }, + attachTo: { id: 'app', input: 'root' }, inputs: { content: createExtensionInput( { @@ -129,9 +129,9 @@ export function convertLegacyApp( }, }); const CoreNavOverride = createExtension({ - namespace: 'core', + namespace: 'app', name: 'nav', - attachTo: { id: 'core/layout', input: 'nav' }, + attachTo: { id: 'app/layout', input: 'nav' }, output: {}, factory: () => ({}), disabled: true, diff --git a/packages/frontend-app-api/src/extensions/Core.tsx b/packages/frontend-app-api/src/extensions/Core.tsx index 99780e231c..ea722ce862 100644 --- a/packages/frontend-app-api/src/extensions/Core.tsx +++ b/packages/frontend-app-api/src/extensions/Core.tsx @@ -25,7 +25,7 @@ import { } from '@backstage/frontend-plugin-api'; export const Core = createExtension({ - namespace: 'core', + namespace: 'app', attachTo: { id: 'root', input: 'default' }, // ignored inputs: { apis: createExtensionInput({ diff --git a/packages/frontend-app-api/src/extensions/CoreLayout.tsx b/packages/frontend-app-api/src/extensions/CoreLayout.tsx index e4f86256f2..2d65dff73a 100644 --- a/packages/frontend-app-api/src/extensions/CoreLayout.tsx +++ b/packages/frontend-app-api/src/extensions/CoreLayout.tsx @@ -23,9 +23,9 @@ import { import { SidebarPage } from '@backstage/core-components'; export const CoreLayout = createExtension({ - namespace: 'core', + namespace: 'app', name: 'layout', - attachTo: { id: 'core/router', input: 'children' }, + attachTo: { id: 'app/router', input: 'children' }, inputs: { nav: createExtensionInput( { diff --git a/packages/frontend-app-api/src/extensions/CoreNav.tsx b/packages/frontend-app-api/src/extensions/CoreNav.tsx index 12e6b08989..9c0ac5e85a 100644 --- a/packages/frontend-app-api/src/extensions/CoreNav.tsx +++ b/packages/frontend-app-api/src/extensions/CoreNav.tsx @@ -79,9 +79,9 @@ const SidebarNavItem = ( }; export const CoreNav = createExtension({ - namespace: 'core', + namespace: 'app', name: 'nav', - attachTo: { id: 'core/layout', input: 'nav' }, + attachTo: { id: 'app/layout', input: 'nav' }, inputs: { items: createExtensionInput({ target: createNavItemExtension.targetDataRef, diff --git a/packages/frontend-app-api/src/extensions/CoreRouter.tsx b/packages/frontend-app-api/src/extensions/CoreRouter.tsx index 3abb7756bc..5c823c2e60 100644 --- a/packages/frontend-app-api/src/extensions/CoreRouter.tsx +++ b/packages/frontend-app-api/src/extensions/CoreRouter.tsx @@ -35,9 +35,9 @@ import { BrowserRouter } from 'react-router-dom'; import { RouteTracker } from '../routing/RouteTracker'; export const CoreRouter = createExtension({ - namespace: 'core', + namespace: 'app', name: 'router', - attachTo: { id: 'core', input: 'root' }, + attachTo: { id: 'app', input: 'root' }, inputs: { signInPage: createExtensionInput( { diff --git a/packages/frontend-app-api/src/extensions/CoreRoutes.tsx b/packages/frontend-app-api/src/extensions/CoreRoutes.tsx index 155a5b60fa..d66c857f3b 100644 --- a/packages/frontend-app-api/src/extensions/CoreRoutes.tsx +++ b/packages/frontend-app-api/src/extensions/CoreRoutes.tsx @@ -25,9 +25,9 @@ import { import { useRoutes } from 'react-router-dom'; export const CoreRoutes = createExtension({ - namespace: 'core', + namespace: 'app', name: 'routes', - attachTo: { id: 'core/layout', input: 'content' }, + attachTo: { id: 'app/layout', input: 'content' }, inputs: { routes: createExtensionInput({ path: coreExtensionData.routePath, diff --git a/packages/frontend-app-api/src/routing/extractRouteInfoFromAppNode.test.ts b/packages/frontend-app-api/src/routing/extractRouteInfoFromAppNode.test.ts index f0ce6ac590..1c332b331f 100644 --- a/packages/frontend-app-api/src/routing/extractRouteInfoFromAppNode.test.ts +++ b/packages/frontend-app-api/src/routing/extractRouteInfoFromAppNode.test.ts @@ -49,7 +49,7 @@ function createTestExtension(options: { name: options.name, attachTo: options.parent ? { id: `test/${options.parent}`, input: 'children' } - : { id: 'core/routes', input: 'routes' }, + : { id: 'app/routes', input: 'routes' }, output: { element: coreExtensionData.reactElement, path: coreExtensionData.routePath.optional(), diff --git a/packages/frontend-app-api/src/tree/createAppTree.test.ts b/packages/frontend-app-api/src/tree/createAppTree.test.ts index 15c8ab4750..9ee58fe2d2 100644 --- a/packages/frontend-app-api/src/tree/createAppTree.test.ts +++ b/packages/frontend-app-api/src/tree/createAppTree.test.ts @@ -24,18 +24,18 @@ import { createAppTree } from './createAppTree'; const extBase = { id: 'test', - attachTo: { id: 'core', input: 'root' }, + attachTo: { id: 'app', input: 'root' }, output: {}, factory: () => ({}), }; describe('createAppTree', () => { - it('throws an error when a core extension is parametrized', () => { + it('throws an error when a app extension is parametrized', () => { const config = new MockConfigApi({ app: { extensions: [ { - core: {}, + app: {}, }, ], }, @@ -48,17 +48,17 @@ describe('createAppTree', () => { ]; expect(() => createAppTree({ features, config, builtinExtensions: [] }), - ).toThrow("Configuration of the 'core' extension is forbidden"); + ).toThrow("Configuration of the 'app' extension is forbidden"); }); - it('throws an error when a core extension is overridden', () => { + it('throws an error when a app extension is overridden', () => { const config = new MockConfigApi({}); const features = [ createExtensionOverrides({ extensions: [ createExtension({ - name: 'core', - attachTo: { id: 'core/routes', input: 'route' }, + name: 'app', + attachTo: { id: 'app/routes', input: 'route' }, inputs: {}, output: {}, factory: () => ({}), @@ -69,7 +69,7 @@ describe('createAppTree', () => { expect(() => createAppTree({ features, config, builtinExtensions: [] }), ).toThrow( - "It is forbidden to override the following extension(s): 'core', which is done by one or more extension overrides", + "It is forbidden to override the following extension(s): 'app', which is done by one or more extension overrides", ); }); diff --git a/packages/frontend-app-api/src/tree/createAppTree.ts b/packages/frontend-app-api/src/tree/createAppTree.ts index 0f8ce09138..12c7f7fc3a 100644 --- a/packages/frontend-app-api/src/tree/createAppTree.ts +++ b/packages/frontend-app-api/src/tree/createAppTree.ts @@ -32,12 +32,12 @@ export interface CreateAppTreeOptions { /** @internal */ export function createAppTree(options: CreateAppTreeOptions): AppTree { const tree = resolveAppTree( - 'core', + 'app', resolveAppNodeSpecs({ features: options.features, builtinExtensions: options.builtinExtensions, parameters: readAppExtensionsConfig(options.config), - forbidden: new Set(['core']), + forbidden: new Set(['app']), }), ); instantiateAppNodeTree(tree.root); diff --git a/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts b/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts index 49f6203ce4..7855b87df2 100644 --- a/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts +++ b/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts @@ -37,7 +37,7 @@ const inputMirrorDataRef = createExtensionDataRef('mirror'); const simpleExtension = resolveExtensionDefinition( createExtension({ - namespace: 'core', + namespace: 'app', name: 'test', attachTo: { id: 'ignored', input: 'ignored' }, output: { @@ -256,7 +256,7 @@ describe('createAppNodeInstance', () => { node: makeNode( resolveExtensionDefinition( createExtension({ - namespace: 'core', + namespace: 'app', name: 'test', attachTo: { id: 'ignored', input: 'ignored' }, inputs: { @@ -300,17 +300,17 @@ describe('createAppNodeInstance', () => { expect(Array.from(instance.getDataRefs())).toEqual([inputMirrorDataRef]); expect(instance.getData(inputMirrorDataRef)).toMatchObject({ optionalSingletonPresent: { - node: { spec: { id: 'core/test' } }, + node: { spec: { id: 'app/test' } }, output: { test: 'optionalSingletonPresent' }, }, singleton: { - node: { spec: { id: 'core/test' } }, + node: { spec: { id: 'app/test' } }, output: { test: 'singleton', other: 2 }, }, many: [ - { node: { spec: { id: 'core/test' } }, output: { test: 'many1' } }, + { node: { spec: { id: 'app/test' } }, output: { test: 'many1' } }, { - node: { spec: { id: 'core/test' } }, + node: { spec: { id: 'app/test' } }, output: { test: 'many2', other: 3 }, }, ], @@ -324,7 +324,7 @@ describe('createAppNodeInstance', () => { attachments: new Map(), }), ).toThrow( - "Invalid configuration for extension 'core/test'; caused by Error: Expected number, received string at 'other'", + "Invalid configuration for extension 'app/test'; caused by Error: Expected number, received string at 'other'", ); }); @@ -334,7 +334,7 @@ describe('createAppNodeInstance', () => { node: makeNode( resolveExtensionDefinition( createExtension({ - namespace: 'core', + namespace: 'app', name: 'test', attachTo: { id: 'ignored', input: 'ignored' }, output: {}, @@ -349,7 +349,7 @@ describe('createAppNodeInstance', () => { attachments: new Map(), }), ).toThrow( - "Failed to instantiate extension 'core/test'; caused by NopeError: NOPE", + "Failed to instantiate extension 'app/test'; caused by NopeError: NOPE", ); }); @@ -359,7 +359,7 @@ describe('createAppNodeInstance', () => { node: makeNode( resolveExtensionDefinition( createExtension({ - namespace: 'core', + namespace: 'app', name: 'test', attachTo: { id: 'ignored', input: 'ignored' }, output: { @@ -375,7 +375,7 @@ describe('createAppNodeInstance', () => { attachments: new Map(), }), ).toThrow( - "Failed to instantiate extension 'core/test', duplicate extension data 'test' received via output 'test2'", + "Failed to instantiate extension 'app/test', duplicate extension data 'test' received via output 'test2'", ); }); @@ -385,7 +385,7 @@ describe('createAppNodeInstance', () => { node: makeNode( resolveExtensionDefinition( createExtension({ - namespace: 'core', + namespace: 'app', name: 'test', attachTo: { id: 'ignored', input: 'ignored' }, output: { @@ -400,7 +400,7 @@ describe('createAppNodeInstance', () => { attachments: new Map(), }), ).toThrow( - "Failed to instantiate extension 'core/test', unknown output provided via 'nonexistent'", + "Failed to instantiate extension 'app/test', unknown output provided via 'nonexistent'", ); }); @@ -410,7 +410,7 @@ describe('createAppNodeInstance', () => { node: makeNode( resolveExtensionDefinition( createExtension({ - namespace: 'core', + namespace: 'app', name: 'test', attachTo: { id: 'ignored', input: 'ignored' }, inputs: { @@ -429,7 +429,7 @@ describe('createAppNodeInstance', () => { attachments: new Map(), }), ).toThrow( - "Failed to instantiate extension 'core/test', input 'singleton' is required but was not received", + "Failed to instantiate extension 'app/test', input 'singleton' is required but was not received", ); }); @@ -457,7 +457,7 @@ describe('createAppNodeInstance', () => { node: makeNode( resolveExtensionDefinition( createExtension({ - namespace: 'core', + namespace: 'app', name: 'test', attachTo: { id: 'ignored', input: 'ignored' }, inputs: { @@ -472,7 +472,7 @@ describe('createAppNodeInstance', () => { ), }), ).toThrow( - "Failed to instantiate extension 'core/test', received undeclared input 'undeclared' from extension 'core/test'", + "Failed to instantiate extension 'app/test', received undeclared input 'undeclared' from extension 'app/test'", ); }); @@ -495,7 +495,7 @@ describe('createAppNodeInstance', () => { node: makeNode( resolveExtensionDefinition( createExtension({ - namespace: 'core', + namespace: 'app', name: 'test', attachTo: { id: 'ignored', input: 'ignored' }, output: {}, @@ -505,7 +505,7 @@ describe('createAppNodeInstance', () => { ), }), ).toThrow( - "Failed to instantiate extension 'core/test', received undeclared inputs 'undeclared1' from extension 'core/test' and 'undeclared2' from extensions 'core/test', 'core/test'", + "Failed to instantiate extension 'app/test', received undeclared inputs 'undeclared1' from extension 'app/test' and 'undeclared2' from extensions 'app/test', 'app/test'", ); }); @@ -524,7 +524,7 @@ describe('createAppNodeInstance', () => { node: makeNode( resolveExtensionDefinition( createExtension({ - namespace: 'core', + namespace: 'app', name: 'test', attachTo: { id: 'ignored', input: 'ignored' }, inputs: { @@ -542,7 +542,7 @@ describe('createAppNodeInstance', () => { ), }), ).toThrow( - "Failed to instantiate extension 'core/test', expected exactly one 'singleton' input but received multiple: 'core/test', 'core/test'", + "Failed to instantiate extension 'app/test', expected exactly one 'singleton' input but received multiple: 'app/test', 'app/test'", ); }); @@ -561,7 +561,7 @@ describe('createAppNodeInstance', () => { node: makeNode( resolveExtensionDefinition( createExtension({ - namespace: 'core', + namespace: 'app', name: 'test', attachTo: { id: 'ignored', input: 'ignored' }, inputs: { @@ -579,7 +579,7 @@ describe('createAppNodeInstance', () => { ), }), ).toThrow( - "Failed to instantiate extension 'core/test', expected at most one 'singleton' input but received multiple: 'core/test', 'core/test'", + "Failed to instantiate extension 'app/test', expected at most one 'singleton' input but received multiple: 'app/test', 'app/test'", ); }); @@ -592,7 +592,7 @@ describe('createAppNodeInstance', () => { node: makeNode( resolveExtensionDefinition( createExtension({ - namespace: 'core', + namespace: 'app', name: 'test', attachTo: { id: 'ignored', input: 'ignored' }, inputs: { @@ -610,7 +610,7 @@ describe('createAppNodeInstance', () => { ), }), ).toThrow( - "Failed to instantiate extension 'core/test', input 'singleton' did not receive required extension data 'other' from extension 'core/test'", + "Failed to instantiate extension 'app/test', input 'singleton' did not receive required extension data 'other' from extension 'app/test'", ); }); }); diff --git a/packages/frontend-app-api/src/tree/readAppExtensionsConfig.test.ts b/packages/frontend-app-api/src/tree/readAppExtensionsConfig.test.ts index 504d5a6197..4531947f9a 100644 --- a/packages/frontend-app-api/src/tree/readAppExtensionsConfig.test.ts +++ b/packages/frontend-app-api/src/tree/readAppExtensionsConfig.test.ts @@ -25,18 +25,18 @@ describe('readAppExtensionsConfig', () => { it('should disable extension with shorthand notation', () => { expect( readAppExtensionsConfig( - new ConfigReader({ app: { extensions: [{ 'core/router': false }] } }), + new ConfigReader({ app: { extensions: [{ 'app/router': false }] } }), ), ).toEqual([ { - id: 'core/router', + id: 'app/router', disabled: true, }, ]); expect( readAppExtensionsConfig( new ConfigReader({ - app: { extensions: [{ 'core/router': { disabled: true } }] }, + app: { extensions: [{ 'app/router': { disabled: true } }] }, }), ), ).toEqual([ @@ -44,7 +44,7 @@ describe('readAppExtensionsConfig', () => { at: undefined, config: undefined, disabled: true, - id: 'core/router', + id: 'app/router', }, ]); }); @@ -52,33 +52,33 @@ describe('readAppExtensionsConfig', () => { it('should enable extension with shorthand notation', () => { expect( readAppExtensionsConfig( - new ConfigReader({ app: { extensions: ['core/router'] } }), + new ConfigReader({ app: { extensions: ['app/router'] } }), ), ).toEqual([ { - id: 'core/router', + id: 'app/router', disabled: false, }, ]); expect( readAppExtensionsConfig( - new ConfigReader({ app: { extensions: [{ 'core/router': true }] } }), + new ConfigReader({ app: { extensions: [{ 'app/router': true }] } }), ), ).toEqual([ { - id: 'core/router', + id: 'app/router', disabled: false, }, ]); expect( readAppExtensionsConfig( new ConfigReader({ - app: { extensions: [{ 'core/router': { disabled: false } }] }, + app: { extensions: [{ 'app/router': { disabled: false } }] }, }), ), ).toEqual([ { - id: 'core/router', + id: 'app/router', disabled: false, }, ]); @@ -89,12 +89,12 @@ describe('readAppExtensionsConfig', () => { readAppExtensionsConfig( new ConfigReader({ app: { - extensions: [{ 'core/router': 'some-string' }], + extensions: [{ 'app/router': 'some-string' }], }, }), ), ).toThrow( - 'Invalid extension configuration at app.extensions[0][core/router], value must be a boolean or object', + 'Invalid extension configuration at app.extensions[0][app/router], value must be a boolean or object', ); }); @@ -156,8 +156,8 @@ describe('expandShorthandExtensionParameters', () => { }); it('supports string key', () => { - expect(run('core/router')).toEqual({ - id: 'core/router', + expect(run('app/router')).toEqual({ + id: 'app/router', disabled: false, }); expect(() => run('')).toThrowErrorMatchingInlineSnapshot( @@ -170,96 +170,96 @@ describe('expandShorthandExtensionParameters', () => { it('supports null value', () => { // this is the result of typing: - // - core/router: + // - app/router: // The missing value is interpreted as null by the yaml parser so we deal with that - expect(run({ 'core/router': null })).toEqual({ - id: 'core/router', + expect(run({ 'app/router': null })).toEqual({ + id: 'app/router', disabled: false, }); }); it('supports boolean value', () => { - expect(run({ 'core/router': true })).toEqual({ - id: 'core/router', + expect(run({ 'app/router': true })).toEqual({ + id: 'app/router', disabled: false, }); - expect(run({ 'core/router': false })).toEqual({ - id: 'core/router', + expect(run({ 'app/router': false })).toEqual({ + id: 'app/router', disabled: true, }); }); it('should not support string values', () => { expect(() => - run({ 'core/router': 'example-package#MyRouter' }), + run({ 'app/router': 'example-package#MyRouter' }), ).toThrowErrorMatchingInlineSnapshot( - `"Invalid extension configuration at app.extensions[1][core/router], value must be a boolean or object"`, + `"Invalid extension configuration at app.extensions[1][app/router], value must be a boolean or object"`, ); }); it('supports object id only in the key', () => { expect(() => - run({ 'core/router': { id: 'some.id' } }), + run({ 'app/router': { id: 'some.id' } }), ).toThrowErrorMatchingInlineSnapshot( - `"Invalid extension configuration at app.extensions[1][core/router].id, unknown parameter; expected one of 'attachTo', 'disabled', 'config'"`, + `"Invalid extension configuration at app.extensions[1][app/router].id, unknown parameter; expected one of 'attachTo', 'disabled', 'config'"`, ); }); it('supports object attachTo', () => { expect( run({ - 'core/router': { attachTo: { id: 'other.root', input: 'inputs' } }, + 'app/router': { attachTo: { id: 'other.root', input: 'inputs' } }, }), ).toEqual({ - id: 'core/router', + id: 'app/router', attachTo: { id: 'other.root', input: 'inputs' }, }); expect(() => run({ - 'core/router': { + 'app/router': { id: 'other-id', }, }), ).toThrowErrorMatchingInlineSnapshot( - `"Invalid extension configuration at app.extensions[1][core/router].id, unknown parameter; expected one of 'attachTo', 'disabled', 'config'"`, + `"Invalid extension configuration at app.extensions[1][app/router].id, unknown parameter; expected one of 'attachTo', 'disabled', 'config'"`, ); }); it('supports object disabled', () => { - expect(run({ 'core/router': { disabled: true } })).toEqual({ - id: 'core/router', + expect(run({ 'app/router': { disabled: true } })).toEqual({ + id: 'app/router', disabled: true, }); - expect(run({ 'core/router': { disabled: false } })).toEqual({ - id: 'core/router', + expect(run({ 'app/router': { disabled: false } })).toEqual({ + id: 'app/router', disabled: false, }); expect(() => - run({ 'core/router': { disabled: 0 } }), + run({ 'app/router': { disabled: 0 } }), ).toThrowErrorMatchingInlineSnapshot( - `"Invalid extension configuration at app.extensions[1][core/router].disabled, must be a boolean"`, + `"Invalid extension configuration at app.extensions[1][app/router].disabled, must be a boolean"`, ); }); it('supports object config', () => { expect( - run({ 'core/router': { config: { disableRedirects: true } } }), + run({ 'app/router': { config: { disableRedirects: true } } }), ).toEqual({ - id: 'core/router', + id: 'app/router', config: { disableRedirects: true }, }); expect(() => - run({ 'core/router': { config: 0 } }), + run({ 'app/router': { config: 0 } }), ).toThrowErrorMatchingInlineSnapshot( - `"Invalid extension configuration at app.extensions[1][core/router].config, must be an object"`, + `"Invalid extension configuration at app.extensions[1][app/router].config, must be an object"`, ); }); it('rejects unknown object keys', () => { expect(() => - run({ 'core/router': { foo: { settings: true } } }), + run({ 'app/router': { foo: { settings: true } } }), ).toThrowErrorMatchingInlineSnapshot( - `"Invalid extension configuration at app.extensions[1][core/router].foo, unknown parameter; expected one of 'attachTo', 'disabled', 'config'"`, + `"Invalid extension configuration at app.extensions[1][app/router].foo, unknown parameter; expected one of 'attachTo', 'disabled', 'config'"`, ); }); }); diff --git a/packages/frontend-app-api/src/tree/resolveAppTree.test.ts b/packages/frontend-app-api/src/tree/resolveAppTree.test.ts index 4fca671554..f964fceb50 100644 --- a/packages/frontend-app-api/src/tree/resolveAppTree.test.ts +++ b/packages/frontend-app-api/src/tree/resolveAppTree.test.ts @@ -36,19 +36,19 @@ const baseSpec = { describe('buildAppTree', () => { it('should fail to create an empty tree', () => { - expect(() => resolveAppTree('core', [])).toThrow( - "No root node with id 'core' found in app tree", + expect(() => resolveAppTree('app', [])).toThrow( + "No root node with id 'app' found in app tree", ); }); it('should create a tree with only one node', () => { - const tree = resolveAppTree('core', [{ ...baseSpec, id: 'core' }]); + const tree = resolveAppTree('app', [{ ...baseSpec, id: 'app' }]); expect(tree.root).toEqual({ - spec: { ...baseSpec, id: 'core' }, + spec: { ...baseSpec, id: 'app' }, edges: { attachments: new Map() }, }); expect(Array.from(tree.orphans)).toEqual([]); - expect(Array.from(tree.nodes.keys())).toEqual(['core']); + expect(Array.from(tree.nodes.keys())).toEqual(['app']); }); it('should create a tree', () => { @@ -159,7 +159,7 @@ describe('buildAppTree', () => { it('throws an error when duplicated extensions are detected', () => { expect(() => - resolveAppTree('core', [ + resolveAppTree('app', [ { ...baseSpec, id: 'a' }, { ...baseSpec, id: 'a' }, ]), diff --git a/packages/frontend-app-api/src/wiring/createApp.test.tsx b/packages/frontend-app-api/src/wiring/createApp.test.tsx index 1cbe3a65ba..d5a206e7fb 100644 --- a/packages/frontend-app-api/src/wiring/createApp.test.tsx +++ b/packages/frontend-app-api/src/wiring/createApp.test.tsx @@ -169,7 +169,7 @@ describe('createApp', () => { extensions: [ createExtension({ name: 'first', - attachTo: { id: 'core', input: 'root' }, + attachTo: { id: 'app', input: 'root' }, output: { element: coreExtensionData.reactElement }, factory() { const Component = () => { @@ -193,9 +193,9 @@ describe('createApp', () => { featureFlags: [{ name: 'test-2' }], extensions: [ createExtension({ - namespace: 'core', + namespace: 'app', name: 'router', - attachTo: { id: 'core', input: 'root' }, + attachTo: { id: 'app', input: 'root' }, disabled: true, output: {}, factory: () => ({}), @@ -242,24 +242,24 @@ describe('createApp', () => { const { tree } = appTreeApi!.getTree(); expect(String(tree.root)).toMatchInlineSnapshot(` - " + " root [ - + children [ - + content [ - + routes [ ] - + ] nav [ - + ] - + ] - + ] components [ @@ -289,7 +289,7 @@ describe('createApp', () => { ] - " + " `); }); }); diff --git a/packages/frontend-app-api/src/wiring/createApp.tsx b/packages/frontend-app-api/src/wiring/createApp.tsx index 337da91708..09a7034ffb 100644 --- a/packages/frontend-app-api/src/wiring/createApp.tsx +++ b/packages/frontend-app-api/src/wiring/createApp.tsx @@ -172,7 +172,7 @@ export function createExtensionTree(options: { ); }, getRootRoutes(): JSX.Element[] { - return this.getExtensionAttachments('core/routes', 'routes').map(node => { + return this.getExtensionAttachments('app/routes', 'routes').map(node => { const path = node.getData(coreExtensionData.routePath); const element = node.getData(coreExtensionData.reactElement); const routeRef = node.getData(coreExtensionData.routeRef); @@ -199,7 +199,7 @@ export function createExtensionTree(options: { ); }; - return this.getExtensionAttachments('core/nav', 'items') + return this.getExtensionAttachments('app/nav', 'items') .map((node, index) => { const target = node.getData(createNavItemExtension.targetDataRef); if (!target) { diff --git a/packages/frontend-plugin-api/src/components/ExtensionBoundary.test.tsx b/packages/frontend-plugin-api/src/components/ExtensionBoundary.test.tsx index 669335d577..66fb3901fc 100644 --- a/packages/frontend-plugin-api/src/components/ExtensionBoundary.test.tsx +++ b/packages/frontend-plugin-api/src/components/ExtensionBoundary.test.tsx @@ -27,7 +27,7 @@ const wrapInBoundaryExtension = (element: JSX.Element) => { const routeRef = createRouteRef(); return createExtension({ name: 'test', - attachTo: { id: 'core/routes', input: 'routes' }, + attachTo: { id: 'app/routes', input: 'routes' }, output: { element: coreExtensionData.reactElement, path: coreExtensionData.routePath, diff --git a/packages/frontend-plugin-api/src/extensions/createApiExtension.test.ts b/packages/frontend-plugin-api/src/extensions/createApiExtension.test.ts index d3bd84bc7f..0636d0d79d 100644 --- a/packages/frontend-plugin-api/src/extensions/createApiExtension.test.ts +++ b/packages/frontend-plugin-api/src/extensions/createApiExtension.test.ts @@ -35,7 +35,7 @@ describe('createApiExtension', () => { version: 'v1', kind: 'api', namespace: 'test', - attachTo: { id: 'core', input: 'apis' }, + attachTo: { id: 'app', input: 'apis' }, disabled: false, configSchema: undefined, inputs: {}, @@ -71,7 +71,7 @@ describe('createApiExtension', () => { version: 'v1', kind: 'api', namespace: 'test', - attachTo: { id: 'core', input: 'apis' }, + attachTo: { id: 'app', input: 'apis' }, disabled: false, configSchema: undefined, inputs: {}, diff --git a/packages/frontend-plugin-api/src/extensions/createApiExtension.ts b/packages/frontend-plugin-api/src/extensions/createApiExtension.ts index e941c4f2a0..1680332960 100644 --- a/packages/frontend-plugin-api/src/extensions/createApiExtension.ts +++ b/packages/frontend-plugin-api/src/extensions/createApiExtension.ts @@ -55,7 +55,7 @@ export function createApiExtension< // Since ApiRef IDs use a global namespace we use the namespace here in order to override // potential plugin IDs and always end up with the format `api:` namespace: apiRef.id, - attachTo: { id: 'core', input: 'apis' }, + attachTo: { id: 'app', input: 'apis' }, inputs: extensionInputs, configSchema, output: { diff --git a/packages/frontend-plugin-api/src/extensions/createComponentExtension.tsx b/packages/frontend-plugin-api/src/extensions/createComponentExtension.tsx index 175b37b144..2efa106750 100644 --- a/packages/frontend-plugin-api/src/extensions/createComponentExtension.tsx +++ b/packages/frontend-plugin-api/src/extensions/createComponentExtension.tsx @@ -54,7 +54,7 @@ export function createComponentExtension< kind: 'component', namespace: options.ref.id, name: options.name, - attachTo: { id: 'core', input: 'components' }, + attachTo: { id: 'app', input: 'components' }, inputs: options.inputs, disabled: options.disabled, configSchema: options.configSchema, diff --git a/packages/frontend-plugin-api/src/extensions/createNavItemExtension.tsx b/packages/frontend-plugin-api/src/extensions/createNavItemExtension.tsx index d2062c74c5..4b92d4dace 100644 --- a/packages/frontend-plugin-api/src/extensions/createNavItemExtension.tsx +++ b/packages/frontend-plugin-api/src/extensions/createNavItemExtension.tsx @@ -35,7 +35,7 @@ export function createNavItemExtension(options: { namespace, name, kind: 'nav-item', - attachTo: { id: 'core/nav', input: 'items' }, + attachTo: { id: 'app/nav', input: 'items' }, configSchema: createSchemaFromZod(z => z.object({ title: z.string().default(title), diff --git a/packages/frontend-plugin-api/src/extensions/createNavLogoExtension.test.tsx b/packages/frontend-plugin-api/src/extensions/createNavLogoExtension.test.tsx index 265b381094..90e1448448 100644 --- a/packages/frontend-plugin-api/src/extensions/createNavLogoExtension.test.tsx +++ b/packages/frontend-plugin-api/src/extensions/createNavLogoExtension.test.tsx @@ -34,7 +34,7 @@ describe('createNavLogoExtension', () => { version: 'v1', kind: 'nav-logo', name: 'test', - attachTo: { id: 'core/nav', input: 'logos' }, + attachTo: { id: 'app/nav', input: 'logos' }, disabled: false, inputs: {}, output: { diff --git a/packages/frontend-plugin-api/src/extensions/createNavLogoExtension.tsx b/packages/frontend-plugin-api/src/extensions/createNavLogoExtension.tsx index 8e2454ddc3..3d66b26d6b 100644 --- a/packages/frontend-plugin-api/src/extensions/createNavLogoExtension.tsx +++ b/packages/frontend-plugin-api/src/extensions/createNavLogoExtension.tsx @@ -31,7 +31,7 @@ export function createNavLogoExtension(options: { kind: 'nav-logo', name: options?.name, namespace: options?.namespace, - attachTo: { id: 'core/nav', input: 'logos' }, + attachTo: { id: 'app/nav', input: 'logos' }, output: { logos: createNavLogoExtension.logoElementsDataRef, }, diff --git a/packages/frontend-plugin-api/src/extensions/createPageExtension.test.tsx b/packages/frontend-plugin-api/src/extensions/createPageExtension.test.tsx index 28f74d544c..2de72296ac 100644 --- a/packages/frontend-plugin-api/src/extensions/createPageExtension.test.tsx +++ b/packages/frontend-plugin-api/src/extensions/createPageExtension.test.tsx @@ -45,7 +45,7 @@ describe('createPageExtension', () => { version: 'v1', name: 'test', kind: 'page', - attachTo: { id: 'core/routes', input: 'routes' }, + attachTo: { id: 'app/routes', input: 'routes' }, configSchema: expect.anything(), disabled: false, inputs: {}, @@ -102,7 +102,7 @@ describe('createPageExtension', () => { version: 'v1', name: 'test', kind: 'page', - attachTo: { id: 'core/routes', input: 'routes' }, + attachTo: { id: 'app/routes', input: 'routes' }, configSchema: expect.anything(), disabled: false, inputs: {}, diff --git a/packages/frontend-plugin-api/src/extensions/createPageExtension.tsx b/packages/frontend-plugin-api/src/extensions/createPageExtension.tsx index 3b936ef210..dfe549f32b 100644 --- a/packages/frontend-plugin-api/src/extensions/createPageExtension.tsx +++ b/packages/frontend-plugin-api/src/extensions/createPageExtension.tsx @@ -67,7 +67,7 @@ export function createPageExtension< kind: 'page', namespace: options.namespace, name: options.name, - attachTo: options.attachTo ?? { id: 'core/routes', input: 'routes' }, + attachTo: options.attachTo ?? { id: 'app/routes', input: 'routes' }, configSchema, inputs: options.inputs, disabled: options.disabled, diff --git a/packages/frontend-plugin-api/src/extensions/createSignInPageExtension.tsx b/packages/frontend-plugin-api/src/extensions/createSignInPageExtension.tsx index ee993b1bc0..543a5447ad 100644 --- a/packages/frontend-plugin-api/src/extensions/createSignInPageExtension.tsx +++ b/packages/frontend-plugin-api/src/extensions/createSignInPageExtension.tsx @@ -50,7 +50,7 @@ export function createSignInPageExtension< kind: 'sign-in-page', namespace: options?.namespace, name: options?.name, - attachTo: options.attachTo ?? { id: 'core/router', input: 'signInPage' }, + attachTo: options.attachTo ?? { id: 'app/router', input: 'signInPage' }, configSchema: options.configSchema, inputs: options.inputs, disabled: options.disabled, diff --git a/packages/frontend-plugin-api/src/extensions/createThemeExtension.ts b/packages/frontend-plugin-api/src/extensions/createThemeExtension.ts index dd6c2f742f..cc6dbdabe9 100644 --- a/packages/frontend-plugin-api/src/extensions/createThemeExtension.ts +++ b/packages/frontend-plugin-api/src/extensions/createThemeExtension.ts @@ -23,7 +23,7 @@ export function createThemeExtension(theme: AppTheme) { kind: 'theme', namespace: 'app', name: theme.id, - attachTo: { id: 'core', input: 'themes' }, + attachTo: { id: 'app', input: 'themes' }, output: { theme: createThemeExtension.themeDataRef, }, diff --git a/packages/frontend-plugin-api/src/extensions/createTranslationExtension.test.ts b/packages/frontend-plugin-api/src/extensions/createTranslationExtension.test.ts index ea57fdbc8f..3712da7185 100644 --- a/packages/frontend-plugin-api/src/extensions/createTranslationExtension.test.ts +++ b/packages/frontend-plugin-api/src/extensions/createTranslationExtension.test.ts @@ -44,7 +44,7 @@ describe('createTranslationExtension', () => { version: 'v1', kind: 'translation', namespace: 'test', - attachTo: { id: 'core', input: 'translations' }, + attachTo: { id: 'app', input: 'translations' }, disabled: false, inputs: {}, output: { @@ -81,7 +81,7 @@ describe('createTranslationExtension', () => { version: 'v1', kind: 'translation', namespace: 'test', - attachTo: { id: 'core', input: 'translations' }, + attachTo: { id: 'app', input: 'translations' }, disabled: false, inputs: {}, output: { @@ -119,7 +119,7 @@ describe('createTranslationExtension', () => { kind: 'translation', namespace: 'test', name: 'sv', - attachTo: { id: 'core', input: 'translations' }, + attachTo: { id: 'app', input: 'translations' }, disabled: false, inputs: {}, output: { diff --git a/packages/frontend-plugin-api/src/extensions/createTranslationExtension.ts b/packages/frontend-plugin-api/src/extensions/createTranslationExtension.ts index 3db29cdeb5..8497a64b88 100644 --- a/packages/frontend-plugin-api/src/extensions/createTranslationExtension.ts +++ b/packages/frontend-plugin-api/src/extensions/createTranslationExtension.ts @@ -26,7 +26,7 @@ export function createTranslationExtension(options: { kind: 'translation', namespace: options.resource.id, name: options.name, - attachTo: { id: 'core', input: 'translations' }, + attachTo: { id: 'app', input: 'translations' }, output: { resource: createTranslationExtension.translationDataRef, }, diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionOverrides.test.ts b/packages/frontend-plugin-api/src/wiring/createExtensionOverrides.test.ts index 6f5f19e29e..de2d2f9a92 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionOverrides.test.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionOverrides.test.ts @@ -38,13 +38,13 @@ describe('createExtensionOverrides', () => { extensions: [ createExtension({ name: 'a', - attachTo: { id: 'core', input: 'apis' }, + attachTo: { id: 'app', input: 'apis' }, output: {}, factory: () => ({}), }), createExtension({ namespace: 'b', - attachTo: { id: 'core', input: 'apis' }, + attachTo: { id: 'app', input: 'apis' }, output: {}, factory: () => ({}), }), @@ -52,7 +52,7 @@ describe('createExtensionOverrides', () => { kind: 'k', namespace: 'c', name: 'n', - attachTo: { id: 'core', input: 'apis' }, + attachTo: { id: 'app', input: 'apis' }, output: {}, factory: () => ({}), }), @@ -65,7 +65,7 @@ describe('createExtensionOverrides', () => { { "$$type": "@backstage/Extension", "attachTo": { - "id": "core", + "id": "app", "input": "apis", }, "configSchema": undefined, @@ -79,7 +79,7 @@ describe('createExtensionOverrides', () => { { "$$type": "@backstage/Extension", "attachTo": { - "id": "core", + "id": "app", "input": "apis", }, "configSchema": undefined, @@ -93,7 +93,7 @@ describe('createExtensionOverrides', () => { { "$$type": "@backstage/Extension", "attachTo": { - "id": "core", + "id": "app", "input": "apis", }, "configSchema": undefined, @@ -116,7 +116,7 @@ describe('createExtensionOverrides', () => { extensions: [ createExtension({ namespace: 'a', - attachTo: { id: 'core', input: 'apis' }, + attachTo: { id: 'app', input: 'apis' }, output: {}, factory: () => ({}), }), diff --git a/packages/frontend-plugin-api/src/wiring/createPlugin.test.ts b/packages/frontend-plugin-api/src/wiring/createPlugin.test.ts index c7f31eb60d..cb02048bdc 100644 --- a/packages/frontend-plugin-api/src/wiring/createPlugin.test.ts +++ b/packages/frontend-plugin-api/src/wiring/createPlugin.test.ts @@ -102,7 +102,7 @@ const Child2 = createExtension({ const outputExtension = createExtension({ name: 'output', - attachTo: { id: 'core', input: 'root' }, + attachTo: { id: 'app', input: 'root' }, inputs: { names: createExtensionInput({ name: nameExtensionDataRef, @@ -150,7 +150,7 @@ describe('createPlugin', () => { await renderWithEffects( createTestAppRoot({ features: [plugin], - config: { app: { extensions: [{ 'core/router': false }] } }, + config: { app: { extensions: [{ 'app/router': false }] } }, }), ); @@ -172,7 +172,7 @@ describe('createPlugin', () => { config: { app: { extensions: [ - { 'core/router': false }, + { 'app/router': false }, { 'test/2': { config: { name: 'extension-2-renamed' }, @@ -210,7 +210,7 @@ describe('createPlugin', () => { features: [plugin], config: { app: { - extensions: [{ 'core/router': false }], + extensions: [{ 'app/router': false }], }, }, }), diff --git a/packages/frontend-test-utils/src/app/createExtensionTester.test.tsx b/packages/frontend-test-utils/src/app/createExtensionTester.test.tsx index 04da2b7e89..40baaa3ac9 100644 --- a/packages/frontend-test-utils/src/app/createExtensionTester.test.tsx +++ b/packages/frontend-test-utils/src/app/createExtensionTester.test.tsx @@ -64,7 +64,7 @@ describe('createExtensionTester', () => { }); const tester = createExtensionTester(extension); expect(() => tester.render()).toThrow( - "Failed to instantiate extension 'core/routes', input 'routes' did not receive required extension data 'core.reactElement' from extension 'test'", + "Failed to instantiate extension 'app/routes', input 'routes' did not receive required extension data 'core.reactElement' from extension 'test'", ); }); @@ -82,7 +82,7 @@ describe('createExtensionTester', () => { const detailsPageExtension = createExtension({ ...defaultDefinition, name: 'details', - attachTo: { id: 'core/routes', input: 'routes' }, + attachTo: { id: 'app/routes', input: 'routes' }, output: { path: coreExtensionData.routePath, element: coreExtensionData.reactElement, @@ -130,7 +130,7 @@ describe('createExtensionTester', () => { const detailsPageExtension = createExtension({ ...defaultDefinition, name: 'details', - attachTo: { id: 'core/routes', input: 'routes' }, + attachTo: { id: 'app/routes', input: 'routes' }, configSchema: createSchemaFromZod(z => z.object({ title: z.string().optional() }), ), diff --git a/packages/frontend-test-utils/src/app/createExtensionTester.tsx b/packages/frontend-test-utils/src/app/createExtensionTester.tsx index fdac4746d5..aae2e5ed32 100644 --- a/packages/frontend-test-utils/src/app/createExtensionTester.tsx +++ b/packages/frontend-test-utils/src/app/createExtensionTester.tsx @@ -64,9 +64,9 @@ const NavItem = (props: { }; const TestCoreNavExtension = createExtension({ - namespace: 'core', + namespace: 'app', name: 'nav', - attachTo: { id: 'core/layout', input: 'nav' }, + attachTo: { id: 'app/layout', input: 'nav' }, inputs: { items: createExtensionInput({ target: createNavItemExtension.targetDataRef, @@ -150,9 +150,9 @@ const AuthenticationProvider = (props: { }; const TestCoreRouterExtension = createExtension({ - namespace: 'core', + namespace: 'app', name: 'router', - attachTo: { id: 'core', input: 'root' }, + attachTo: { id: 'app', input: 'root' }, inputs: { signInPage: createExtensionInput( { @@ -195,10 +195,10 @@ export class ExtensionTester { ): ExtensionTester { const tester = new ExtensionTester(); const { output, factory, ...rest } = toInternalExtensionDefinition(subject); - // attaching to core/routes to render as index route + // attaching to app/routes to render as index route const extension = createExtension({ ...rest, - attachTo: { id: 'core/routes', input: 'routes' }, + attachTo: { id: 'app/routes', input: 'routes' }, output: { ...output, path: coreExtensionData.routePath, diff --git a/packages/frontend-test-utils/src/app/renderInTestApp.tsx b/packages/frontend-test-utils/src/app/renderInTestApp.tsx index f4011535a4..0cd05741b0 100644 --- a/packages/frontend-test-utils/src/app/renderInTestApp.tsx +++ b/packages/frontend-test-utils/src/app/renderInTestApp.tsx @@ -27,7 +27,7 @@ import { createExtensionTester } from './createExtensionTester'; export function renderInTestApp(element: JSX.Element) { const extension = createExtension({ namespace: 'test', - attachTo: { id: 'core', input: 'root' }, + attachTo: { id: 'app', input: 'root' }, output: { element: coreExtensionData.reactElement, }, From 39d911f201a74371842d7ee54c852b58b832012e Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Tue, 19 Dec 2023 10:38:09 +0100 Subject: [PATCH 272/275] Switch to exit mode Signed-off-by: Vincenzo Scamporlino --- .changeset/pre.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/pre.json b/.changeset/pre.json index e6a57efb1f..b57788819b 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -1,5 +1,5 @@ { - "mode": "pre", + "mode": "exit", "tag": "next", "initialVersions": { "example-app": "0.2.89", From d88388a586fc63b40de23b6d97bd7536fd40f77c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Tue, 19 Dec 2023 10:38:15 +0100 Subject: [PATCH 273/275] Update .changeset/honest-hounds-exist.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/honest-hounds-exist.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/honest-hounds-exist.md b/.changeset/honest-hounds-exist.md index 56fb9a2734..59219e98af 100644 --- a/.changeset/honest-hounds-exist.md +++ b/.changeset/honest-hounds-exist.md @@ -2,4 +2,4 @@ '@backstage/core-components': patch --- -when use LogViewer with big size(more then 30M maybe) logs cause maximun call stack error +Fixes a problem where the `LogViewer` was not able to handle very large logs From b4eed334e189aced3b3891ea0b1fd61334967e8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Tue, 19 Dec 2023 10:50:56 +0100 Subject: [PATCH 274/275] refer to the term 'extension config' much more explicitly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- docs/frontend-system/utility-apis/02-creating.md | 8 ++++---- docs/frontend-system/utility-apis/04-configuring.md | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/frontend-system/utility-apis/02-creating.md b/docs/frontend-system/utility-apis/02-creating.md index 4b87a1dfe0..5e4abadbf4 100644 --- a/docs/frontend-system/utility-apis/02-creating.md +++ b/docs/frontend-system/utility-apis/02-creating.md @@ -88,7 +88,7 @@ The resulting extension ID of the work API will be the kind `api:` followed by t ## Adding configurability -Here we will describe how to amend a utility API with the capability of being configured in app-config. You do this by giving a config schema to your API extension factory function. Let's make the required additions to our original work example API. +Here we will describe how to amend a utility API with the capability of having extension config, which is driven by [your app-config](../../conf/writing.md). You do this by giving an extension config schema to your API extension factory function. Let's make the required additions to our original work example API. ```tsx title="in @internal/plugin-example" /* highlight-add-next-line */ @@ -120,11 +120,11 @@ const exampleWorkApi = createApiExtension({ }); ``` -We wanted users to be able to configure a `goSlow` parameter for our API instances. So we passed in a `configSchema` to `createApiExtension` which matches that interface. This example builds it using [the zod library](https://zod.dev/). The actual config values will then be passed in a type safe manner in to the `factory` which is now a callback, wherein we can do what we wish with them. When changing to the callback form, we also had to add a top level `api: workApiRef` under `createApiExtension`. +We wanted users to be able to set a `goSlow` extension config parameter for our API instances. So we passed in a `configSchema` to `createApiExtension` which matches that interface. This example builds it using [the zod library](https://zod.dev/). The actual extension config values will then be passed in a type safe manner in to the `factory` which is now a callback, wherein we can do what we wish with them. When changing to the callback form, we also had to add a top level `api: workApiRef` under `createApiExtension`. -Note that while we use the word "config" here, it's _not_ the same thing as the `configApi` which gives you access to the full app-config. The config discussed here is instead the particular configuration settings given to your utility API instance. This is discussed more [in the Configuring section below](./04-configuring.md). +Note that the expression "extension config" as used here, is _not_ the same thing as the `configApi` which gives you access to the full app-config. The extension config discussed here is instead the particular configuration settings given to your utility API instance. This is discussed more [in the Configuring section](./04-configuring.md). -Note also that the config schema contained a default value fo the `goSlow` field. This is an important consideration. You want users of your API to be able to make maximum use of it, without having to dive deep into how to configure it. For that reason you generally want to provide as many sane defaults as possible, while letting users override them rarely but with purpose, only when called for. If you have a config schema without defaults, the framework will refuse to instantiate the utility API on startup unless the user had configured those values explicitly. Since it had a default value, the TypeScript code and interfaces also don't have to defensively allow `undefined` - we know that it'll have either the default value or an overridden value when we start consuming the config data. +Note also that the extension config schema contained a default value fo the `goSlow` field. This is an important consideration. You want users of your API to be able to get maximum value out of it, without having to dive deep into how to configure it. For that reason you generally want to provide as many sane defaults as possible, while letting users override them rarely but with purpose, only when called for. If you have an extension config schema without defaults, the framework will refuse to instantiate the utility API on startup unless the user had configured those values explicitly. Since it had a default value, the TypeScript code and interfaces also don't have to defensively allow `undefined` - we know that it'll have either the default value or an overridden value when we start consuming the extension config data. ## Adding inputs diff --git a/docs/frontend-system/utility-apis/04-configuring.md b/docs/frontend-system/utility-apis/04-configuring.md index 602caf0efc..3a5e55560c 100644 --- a/docs/frontend-system/utility-apis/04-configuring.md +++ b/docs/frontend-system/utility-apis/04-configuring.md @@ -6,7 +6,7 @@ sidebar_label: Configuring description: Configuring, extending, and overriding utility APIs --- -Utility APIs are extensions and can therefore optionally be amended with configurability, as well as inputs that other extensions attach themselves to. This section describes how to add those capabilities to your own utility APIs, and how to make use of them as a consumer of such utility APIs. +Utility APIs are extensions and can therefore optionally be amended with configurability, as well as inputs that other extensions attach themselves to. This section describes how to make use of that as a consumer of such utility APIs. ## Configuring @@ -25,7 +25,7 @@ app: It's important to note that the `extensions` are a list (mind the initial `-`), and that the `api:plugin.example.work` entry is an object such that the `config` key needs to be indented below it. If you do not get those two pieces right, the application may not start up correctly. -The config schema of the extension will tell you what configuration parameters it supports. Here we override the `goSlow` configuration value, which replaces the default. +The extension config schema will tell you what parameters it supports. Here we override the `goSlow` extension config value, which replaces the default. ## Attaching extensions to inputs @@ -71,4 +71,4 @@ export default createApp({ In this example the overriding extension is kept minimal, but just like any other extension it can also have `deps`, configurability, and inputs. Check out [the Creating section](./02-creating.md) for more details about that. -When you create a replacement extension, in general you may want to mimic its config schema or input shapes where applicable. This makes it an easier thing to slot in to an app, since it'll be responding to extensibility the same way as the original one did. +When you create a replacement extension, in general you may want to mimic its extension config schema or input shapes where applicable. This makes it an easier thing to slot in to an app, since it'll be responding to extensibility the same way as the original one did. From 734c40811ceaa8f08a55ac67585b927b3946d514 Mon Sep 17 00:00:00 2001 From: blam Date: Tue, 19 Dec 2023 11:02:28 +0100 Subject: [PATCH 275/275] chore: update comment and api-reprots Signed-off-by: blam --- plugins/scaffolder-react/api-report-alpha.md | 6 ++++-- .../src/next/components/Workflow/Workflow.tsx | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/plugins/scaffolder-react/api-report-alpha.md b/plugins/scaffolder-react/api-report-alpha.md index 615b54df84..dc698e0c51 100644 --- a/plugins/scaffolder-react/api-report-alpha.md +++ b/plugins/scaffolder-react/api-report-alpha.md @@ -64,8 +64,10 @@ export const DefaultTemplateOutputs: (props: { output?: ScaffolderTaskOutput; }) => React_2.JSX.Element | null; -// @alpha (undocumented) -export const EmbeddableWorkflow: (props: WorkflowProps) => React_2.JSX.Element; +// @alpha +export const EmbeddableWorkflow: ( + workflowProps: WorkflowProps, +) => JSX.Element | null; // @alpha export const extractSchemaFromStep: (inputStep: JsonObject) => { diff --git a/plugins/scaffolder-react/src/next/components/Workflow/Workflow.tsx b/plugins/scaffolder-react/src/next/components/Workflow/Workflow.tsx index c2ea544463..4a3758cfa9 100644 --- a/plugins/scaffolder-react/src/next/components/Workflow/Workflow.tsx +++ b/plugins/scaffolder-react/src/next/components/Workflow/Workflow.tsx @@ -126,7 +126,7 @@ export const Workflow = (workflowProps: WorkflowProps): JSX.Element | null => { /** * TODO(blam): work out what we want to do with these components in the new API. - * Should we really have EmbeddableWorkflow -> Workflow -> Stepper -> Form, or should we revisit this? + * Should we really have EmbeddableWorkflow, Workflow, Stepper and Form, or should we revisit this? * @alpha */ export const EmbeddableWorkflow = Workflow;